模組:沙盒/Lopullinen
外观
测试区
- package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found
- package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found
- package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found
- package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found
package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found
备忘录
-- 获取页面信息
mw.title.getCurrentTitle().text -- 獲取頁面標題,不含命名空間
-- 调用Mediawiki模板
mw.getCurrentFrame():expandTemplate{ title = "template", args = { "arg1", "arg2", name = "arg3" } } -- {{template|args1|args2|name=args3}}
mw.getCurrentFrame():callParserFunction{ name = "#tag", args = { "nowiki", "some text" } } -- {{#tag:nowiki|some text}}
-- 字符串处理
_, _, capture1, capture2 = mw.ustring.find(source_text, "(.+)blah blah(.+)") -- 分組捕獲
new_string = mw.ustring.gsub(old_string, ptn, replacement) -- 替换
require("strict")
local getArgs = require("Module:Arguments").getArgs
local issue_item_data = mw.loadData("Module:Current VGNL/items")
--- @alias ISSUE_ID [number, number]
--- @alias DATE [number, number, number]
--- @alias RELEASED_STATUS "released" | "pending" | "ondraft" | "cancelled"
--- @alias COLUMN_NAME "feature" | "interview" | "news" | "quaility_content"
--- @class ISSUE_ITEM
--- @field id ISSUE_ID
--- @field issue string
--- @field date DATE | false | nil
--- @field feature string | nil
--- @field interview string | "LEFT" | nil
--- @alias ISSUE_ITEMS ISSUE_ITEM[]
local __all__ = {
"target",
"link",
"index",
"toc",
}
local ROOT_PATH = "維基專題:電子遊戲/簡訊"
-- ===== 跪求Lua 5.4,Lua 5.1要什麼功能什麼沒有🤣 ===== --
--- Check whether there is an item in a list-like table.
--- @param __item any
--- @param __list any[]
--- @return boolean
local function in_list(__item, __list)
for _, v in ipairs(__list) do
if __item == v then
return true
end
end
return false
end
--- Filter one or all items by the condition.
--- @param __function function
--- @param __list table<any, any>
--- @param __mode "all" | "one" | nil @Default to "all".
--- @return any | table<any, any>
local function filter(__function, __list, __mode)
-- Filter one result
if __mode == "one" then
for _, v in pairs(__list) do
if __function(v) then
return v
end
end
return
end
-- Filter all results
local result = {}
for _, v in pairs(__list) do
if __function(v) then
table.insert(result, v)
end
end
return result
end
--- Sort a table and return as a copy.
--- @param __table table<any, any>
--- @param key function
--- @return table<any, any>
local function sorted(__table, key)
-- Make a shallow copy.
local tbl = {}
for k, v in pairs(__table) do
tbl[k] = v
end
-- Then sort that copied table.
table.sort(tbl, key)
return tbl
end
-- ===== Some tools. ===== --
--- Format an issue id tuple to a string.
--- For exmaple: `{2024, 07}` -> "2024-07".
--- @param val ISSUE_ID
--- @return string
local function format_issue_id(val)
local vol, iss = val[1], val[2]
return vol .. "-" .. string.format("%02d", iss)
end
--- Parse a id issue string to a id tuple.
--- For exmaple: "2024-07" -> `{2024, 07}`.
--- @param val string
--- @return ISSUE_ID
local function parse_issue_id(val)
local _, _, _y, _m = mw.ustring.find(val, "(%d%d%d%d)%-(%d%d)")
local y, m = tonumber(_y), tonumber(_m)
return {y, m}
end
--- Format a date table to a Chinese date string.
--- For exmaple: `{2025, 3, 25}` -> "2025年3月25日".
--- @param val DATE
--- @return string
local function format_date(val)
local y, m, d = val[1], val[2], val[3]
return string.format("%s年%s月%s日", y, m, d)
end
--- Get the first issue by a specified field.
--- @param items ISSUE_ITEMS
--- @param id string | "upcoming" | nil
--- @return ISSUE_ITEM
local function get_issue_item(items, id)
local cond, sorter
-- Match recently released issue.
if (id == nil) or (id == "released") then
cond = function(item)
return type(item.date) == "table"
end
local filtered_items = filter(cond, items)
return filtered_items[#filtered_items]
end
-- Match the next upcoming issue
if id == "upcoming" then
cond = function(item)
return item.date == nil
end
local filtered_items = filter(cond, items)
return filtered_items[1]
end
-- Match issue id text (e.g. "2020-01")
local parsed_id = parse_issue_id(id)
cond = function(item)
return (item.id[1] == parsed_id[1]) and (item.id[2] == parsed_id[2])
end
return filter(cond, items, "one")
end
--- Get the link target (i.e. page title) of a issue data by column.
--- @param item ISSUE_ITEM
--- @param column COLUMN_NAME?
--- @return string
local function get_link_target(item, column)
local id_path = format_issue_id(item.id)
local issue_base_path = ROOT_PATH .. "/" .. id_path
if column == nil then
return issue_base_path
end
local code_to_path_mapping = {
["feature"] = "專題",
["interview"] = "訪談",
["news"] = "宣告",
["quaility_content"] = "特優內容",
}
return issue_base_path .. "/" .. code_to_path_mapping[column]
end
--- @param item ISSUE_ITEM
--- @param column COLUMN_NAME?
--- @return string?
local function get_index_text(item, column)
local text
if column == nil then
return format_issue_id(item.id)
end
if in_list(column, {"news", "quaility_content"}) then
return "連結"
end
if in_list(column, {"feature", "interview"}) then
return item[column]
end
end
---
--- @param item ISSUE_ITEM
--- @param column COLUMN_NAME?
--- @return string?
local function get_toc_text(item, column)
local text
if column == nil then
return item.issue
end
if column == "feature" then
local title = item[column]
if title == nil then
return
end
return "專題報導:" .. title
end
if (column == "interview") then
local title = item[column]
if (title == nil) or (title == "LEFT") then
return
end
return "訪談:" .. title
end
if column == "news" then
return "宣告"
end
if column == "quaility_content" then
return "高品質內容變動"
end
end
---
--- @param target string?
--- @param display string?
--- @return string
local function build_linked_text(target, display)
if target == nil then
return display
end
if display == nil then
return "[[" .. target .. "]]"
end
return "[[" .. target .. "|" .. display .. "]]"
end
-- ===== Index table builders ===== --
--- Build the header row.
--- @return table<string, any>
local function build_index_table_header_row()
local row, cell = mw.html.create("tr"), nil
-- Append the no. header cell.
cell = mw.html.create("th")
cell
:attr("scope", "col")
:attr("data-sort-type", "number")
:wikitext("序號")
row:node(cell)
-- Append the id issue header cell.
cell = mw.html.create("th")
cell
:attr("scope", "col")
:attr("data-sort-type", "text")
:wikitext("期數")
row:node(cell)
--Append the header cells.
local headers = {"出刊日期", "專題", "訪談", "宣告", "特優內容"}
for _, header in ipairs(headers) do
cell = mw.html.create("th")
cell
:attr("scope", "col")
:addClass("unsortable")
:wikitext(header)
row:node(cell)
end
return row
end
--- Build the content row.
--- @param index number
--- @param item ISSUE_ITEM
--- @return table<string, any>
local function build_index_table_issue_row(index, item)
local row, cell = mw.html.create("tr"), nil
local target, display, text
-- Append the row header cell.
text = tostring(index)
cell = mw.html.create("th")
cell:attr("scope", "row"):wikitext(text)
row:node(cell)
-- Append the issue cell.
target = get_link_target(item)
display = get_index_text(item)
text = build_linked_text(target, display)
cell = mw.html.create("td")
cell:attr("data-sort-value", item.id):wikitext(text)
row:node(cell)
-- Append the published date cell.
text = format_date(item.date)
cell = mw.html.create("td")
cell:wikitext(text)
row:node(cell)
-- Append feature and interview cell.
if get_index_text(item, "interview") == "LEFT" then
-- Append the spanning feature cell.
target = get_link_target(item, "feature")
display = get_index_text(item, "feature")
text = build_linked_text(target, display)
cell = mw.html.create("td")
cell:attr("colspan", 2):wikitext(text)
row:node(cell)
else
-- Append the feature cell.
display = get_index_text(item, "feature")
if display then
target = get_link_target(item, "feature")
text = build_linked_text(target, display)
else
text = "—"
end
cell = mw.html.create("td")
cell:wikitext(text)
row:node(cell)
-- Append the interview cell.
display = get_index_text(item, "interview")
if display then
target = get_link_target(item, "interview")
text = build_linked_text(target, display)
else
text = "—"
end
cell = mw.html.create("td")
cell:wikitext(text)
row:node(cell)
end
-- Append the news cell.
target = get_link_target(item, "news")
display = get_index_text(item, "news")
text = build_linked_text(target, display)
cell = mw.html.create("td")
cell:attr("data-sort-value", item.id):wikitext(text)
row:node(cell)
-- Append the quaility content cell.
target = get_link_target(item, "quaility_content")
display = get_index_text(item, "quaility_content")
text = build_linked_text(target, display)
cell = mw.html.create("td")
cell:attr("data-sort-value", item.id):wikitext(text)
row:node(cell)
-- Return the row
return row
end
--- Build the index table.
--- @param items ISSUE_ITEMS
--- @return table<string, any>
local function build_table(items)
local table_title = "《電子遊戲專題簡訊》目錄"
local result, child = mw.html.create("table"), nil
result
:addClass("wikitable")
:addClass("sortable")
:css("text-align", "center")
-- Append caption.
child = mw.html.create("caption")
child:wikitext(table_title)
result:node(child)
-- Append the header row.
child = build_index_table_header_row()
result:node(child)
-- Append the issue rows.
for id, item in ipairs(items) do
child = build_index_table_issue_row(id, item)
result:node(child)
end
-- We done.
return result
end
-- ===== Function to be called. ===== --
local p = {}
--- Create a function that invokes a module function with given args.
--- @param func_name string
--- @return function
local function create_invoke_wrapper(func_name)
return function(frame)
local args = getArgs(frame)
return p[func_name](args)
end
end
--- Retrieve link target from the most recent one with the given status.
--- @param args table
--- @return string?
function p._target(args)
local id, column = args[1], args.column
local item = get_issue_item(issue_item_data, id)
return get_link_target(item, column)
end
--- Retrieve link from the most recent one with the given status.
--- @param args table
--- @return string?
function p._link(args)
local id, column = args[1], args.column
local item = get_issue_item(issue_item_data, id)
local target = get_link_target(item, column)
local text = get_toc_text(item, column)
return build_linked_text(target, text)
end
--- Retrieve content from the most recent one with the given status.
--- @param args table
--- @return string?
function p._toc(args)
local id, style = args[1], args.style
local item = get_issue_item(issue_item_data, id)
local linked_texts = {}
local columns = {"feature", "interview", "news", "quaility_content"}
for _, column in ipairs(columns) do
local text = get_toc_text(item, column)
if (text ~= "LEFT") and (text ~= nil) then
local target = get_link_target(item, column)
local link = build_linked_text(target, text)
table.insert(linked_texts, link)
end
end
-- Apply style.
if style == "inline" then
return table.concat(linked_texts, "、")
end
for k, v in ipairs(linked_texts) do
linked_texts[k] = "* " .. v
end
return table.concat(linked_texts, "\n")
end
--- Build and return the index wikitext table.
--- @param args table
--- @return string
function p._index(args)
return tostring(build_table(issue_item_data))
end
-- ===== Return results ===== --
for _, v in ipairs(__all__) do
p[v] = create_invoke_wrapper("_" .. v)
end
return p