模組:ACGaward/nominee check new
外观

標籤定義於子頁面。
子頁面設計旨在避免在變動代碼時影響過往的存檔。僅當刪除或調整原有標籤時,才需要新建子頁面。例如:
假設將
local rules = {
["2-c"] = { "丙級", 1, aliases = { 'c', '2a' } },
["2-b"] = { "乙級", 3, aliases = { 'b', '2b' } },
["2-ga"] = { "優良", 5, aliases = { 'ga', '2c' } },
["2-fa"] = { "典特", 10, aliases = { 'fa', '2d' } },
}
變更為
local rules = {
["2-c"] = { "丙級", 1, aliases = { 'c', '2a' } },
["2-b"] = { "乙級", 3, aliases = { 'b', '2b' } },
["2-ga"] = { "優良", 5, aliases = { 'ga', '2c' } },
["2-a"] = { "甲級", 7, aliases = { 'a', '2d' } },
["2-fa"] = { "典特", 10, aliases = { 'fa', '2e' } },
}
新版本的2d
從「典特」變為「甲級」,為避免以前存檔中的2d
也變化,才需要新設子頁面。
新增單純標籤不會影響以前存檔,為故直接在當前子頁面調整即可。
子頁面列表
[编辑]
require('strict')
local str = mw.ustring
local split = mw.text.split
local getArgs = require("Module:Arguments").getArgs
local CURRENT_RULES_VERSION = '1'
---@alias RuleCode string
---@alias Rule { [1]: string, [2]: number, aliases: RuleCode[] }
---@alias Rules table<RuleCode, Rule>
--- @param ver string?
--- @param strict boolean
--- @return Rules
local function load_rules(ver, strict)
if strict ~= false and ver == nil then
error('需指定規則版本號`|ver=' .. CURRENT_RULES_VERSION .. '`')
end
local version = ver or CURRENT_RULES_VERSION
local rules_page = 'Module:ACGaward/nominee check new/' .. version
return mw.loadData(rules_page)
end
--- @param text string
--- @param status string
--- @return string
local function with_icon(text, status)
local icon_table = {
["yes"] = "[[File:Green check.svg|13px|alt=✓|link=]]",
["partly"] = "[[File:Yellow check.svg|13px|alt=✓|link=]]",
["no"] = "[[File:Red x.svg|13px|alt=✗|link=]]"
}
return icon_table[status] .. ' ' .. text
end
---@param criteria_table Rules
---@param code RuleCode
---@return string
---@return table
local function parse_code(criteria_table, code)
if code == nil then
return nil
end
local normalized_code = str.lower(code)
local rule = criteria_table[normalized_code]
if criteria_table[normalized_code] then
return normalized_code, rule
end
for k, v in pairs(criteria_table) do
for _, w in ipairs(v.aliases) do
if w == normalized_code then
return k, v
end
end
end
end
---@param criteria_table Rules
---@param text string
---@return string?
---@return string?
---@return number?
---@return boolean?
local function parse_item(criteria_table, text)
local _, _, code_, pending_mark = str.find(text, "^([0-9A-Za-z-]+)([??]?)")
local code, rule = parse_code(criteria_table, code_)
if rule == nil then
return
end
local _, _, annotation = str.find(text, "[((](.+)[))]")
annotation = annotation or rule[1]
local _, _, score = str.find(text, "%[(%d+%.?%d-)%]")
score = score and tonumber(score) or rule[2]
local pending = (pending_mark ~= "")
return code, annotation, score, pending
end
---@param code string
---@param annotation string
---@param pending boolean
---@return string
local function item_string(code, annotation, pending)
local template = '<span style="margin-right: 0.2em; font-weight: bold;">%s</span><small>%s</small>'
if pending then
template = "''" .. template .. "''"
end
return str.format(template, str.sub(code, 1, 1), annotation)
end
---In seek of defamiliarization.
---@param num number
---@return string
local function frac_format(num)
if num == 0 then
return "?"
end
local integer, decimal = math.modf(num)
if decimal == 0.5 then
if integer == 0 then
return '½'
end
return tostring(integer) .. '½'
end
return tostring(num)
end
---@param config_table Rules
---@param text string
---@return string
---@return number
local function generate_result(config_table, text)
local items = {}
local string_fragments = split(text, "%s+")
for _, string_fragment in ipairs(string_fragments) do
local code, annotation, score, pending = parse_item(config_table, string_fragment)
if code then
table.insert(items, { code, annotation, score, pending })
end
end
local result_string_fragments, total_score = {}, 0
for _, v in ipairs(items) do
table.insert(result_string_fragments, item_string(v[1], v[2], v[4]))
total_score = total_score + v[3]
end
return table.concat(result_string_fragments, '、'), total_score
end
local p = {}
local function makeInvokeFunc(funcName)
return function(frame)
local args = getArgs(frame)
return p[funcName](args)
end
end
p.main = makeInvokeFunc("_main")
function p._main(args)
if args[1] == nil then
return
end
if args[1] == "0" then
return with_icon("'''不得分'''。", "no")
end
local criteria = load_rules(args.ver)
local _result, _score = generate_result(criteria, args[1])
local yes_result = str.format("符合%s,'''得%s分'''", _result, frac_format(_score))
if args.no == nil then
return with_icon(yes_result .. '。', 'yes')
end
_result, _score = generate_result(criteria, args.no)
local no_result = str.format("不符合%s", _result)
return with_icon(yes_result .. ";" .. no_result .. "。", 'partly')
end
p.request = makeInvokeFunc("_request")
function p._request(args)
if args[1] == nil then
return
end
local criteria = load_rules(args.ver)
local _result, _score = generate_result(criteria, args[1])
if _result == "" then
return args[1]
end
return str.format("%s,計%s分", _result, frac_format(_score))
end
p.item_doc = makeInvokeFunc('_item_doc')
function p._item_doc(args)
local criteria = load_rules(args.ver, false)
local normalized_code = parse_code(criteria, args[1])
local rule = criteria[normalized_code]
if rule == nil then
return
end
return str.format('<code>%s</code> — %s(%s分)', args[1], rule[1], frac_format(rule[2]))
end
p.rules_ver = makeInvokeFunc('_rules_ver')
function p._rules_ver(args)
return CURRENT_RULES_VERSION
end
return p