模組:沙盒/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 DATE_TYPE [number, number, number]
--- @alias ISSUE_ITEM table<string, (string | DATE_TYPE)?>
--- @alias ISSUE_ITEMS ISSUE_ITEM[]
local __all__ = {"target", "link", "content", "index"}
local BASE_TITLE = "維基專題:電子遊戲/簡訊"
local COLUMN_CODE_MAPPING = {
["issue"] = "期號",
["feature"] = "專題",
["interview"] = "訪談",
["news"] = "宣告",
["quaility_content"] = "特優內容",
}
local DATE_STATUS_MAPPING = {
["pending"] = "(待定稿)",
["ondraft"] = "(編寫中)",
["planning"] = "(待採編)",
["cancelled"] = "(未付梓)",
}
-- ===== 何時升級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 items that meet a condition in a table.
--- @param __function function
--- @param __table table<any, any>
--- @return table<any, any>
local function filter(__function, __table)
local result = {}
for k, v in pairs(__table) do
if __function(v) then
result[k] = v
end
end
return result
end
-- ===== Some tools. ===== --
--- Get the first issue by a specified field.
--- @param items ISSUE_ITEMS
--- @param key string
--- @param first "new" | "old"
--- @return ISSUE_ITEM?
local function get_one_issue(items, key, first)
if #items == 0 then
return
end
local sorter = function(a, b)
if first == "new" then
return a[key] >= b[key]
end
return a[key] <= b[key]
end
table.sort(items, sorter)
return items[1]
end
--- Get the recent issue data.
--- @param items ISSUE_ITEMS
--- @param status "published" | "pending" | "ondraft" | "planning" | any
--- @return ISSUE_ITEM?
local function get_recent_issue(items, status)
-- For upcoming issues, get the one with the minimum id.
if in_list(status, {"pending", "ondraft", "planning"}) then
local filter_func = function(x)
return x.date == status
end
local issues = filter(filter_func, items)
return get_one_issue(issues, "id", "old")
end
-- Other status but not nil (e.g. "cancelled") leads a nil result.
if (status ~= nil) and (status ~= "published") then
return
end
-- Now handle the published issues.
local filter_func = function(x)
return type(x.date) == "table"
end
local issues = filter(filter_func, items)
return get_one_issue(issues, "id", "new")
end
--- Turn date table to Chinese date, or status code to text.
--- @param date string | DATE_TYPE
--- @return string
local function humanize_date(date)
if type(date) == "table" then
return string.format("%s年%s月%s日", date[1], date[2], date[3])
end
return DATE_STATUS_MAPPING[date] or ""
end
--- Get the link target (i.e. page title) of a issue data by column.
--- @param item ISSUE_ITEM
--- @param column
--- | nil # 期數
--- | "issue" # 期數
--- | "feature" # 專題報導
--- | "interview" # 訪談
--- | "news" # 宣告
--- | "quaility_content" # 特優內容
--- @return string
local function get_link_target(item, column)
local issue_base_title = BASE_TITLE .. "/" .. item.id
if (column == nil) or (column == "issue") then
return issue_base_title
end
return issue_base_title .. "/" .. COLUMN_CODE_MAPPING[column]
end
--- Get the text.
--- @param item ISSUE_ITEM
--- @param column
--- | nil # 期數
--- | "issue" # 期數
--- | "feature" # 專題報導
--- | "interview" # 訪談
--- | "news" # 宣告
--- | "quaility_content" # 特優內容
--- @param raw boolean?
--- @return string -- noqa
local function get_text(item, column, raw)
local text
if column == nil then
text = item.id
elseif in_list(column, {"issue", "feature"}) then
text = item[column]
elseif column == "interview" then
if (raw == false) and (item.interview == "LEFT") then
text = item.feature
else
text = item.interview
end
else
text = COLUMN_CODE_MAPPING[column]
end
return text
end
--- Build a wikilink text.
--- @param item ISSUE_ITEM
--- @param column
--- | nil # 期数
--- | "issue" # 期數
--- | "feature" # 專題報導
--- | "interview" # 訪談
--- | "news" # 宣告
--- | "quaility_content" # 特優內容
--- @param raw boolean?
--- @return string?
local function get_wikilink(item, column, raw)
local target = get_link_target(item, column)
local text = get_text(item, column, raw)
if target and text then
return string.format("[[%s|%s]]", target, text)
end
end
-- ===== Index table builders ===== --
--- Build the header row.
--- @return table<string, any>
local function build_table_header_row()
local tr, cell = mw.html.create("tr"), nil
-- Append the id cell.
cell = mw.html.create("th")
cell
:attr("scope", "col")
:attr("data-sort-type", "number")
:wikitext("序號")
tr:node(cell)
-- Append the id issue.
cell = mw.html.create("th")
cell
:attr("scope", "col")
:attr("data-sort-type", "text")
:wikitext("期數")
tr:node(cell)
-- Appden the published date cell.
cell = mw.html.create("th")
cell
:attr("scope", "col")
:addClass("class")
:wikitext("出刊日期")
tr:node(cell)
--Append the content cells.
local columns = {"feature", "interview", "news", "quaility_content"}
for _, v in ipairs(columns) do
cell = mw.html.create("th")
cell
:attr("scope", "col")
:addClass("class")
:wikitext(COLUMN_CODE_MAPPING[v])
tr:node(cell)
end
return tr
end
--- Build the content row.
--- @param index number
--- @param item ISSUE_ITEM
--- @return table<string, any>
local function build_table_issue_row(index, item)
local tr, cell = mw.html.create("tr"), nil
-- Append the row header cell.
cell = mw.html.create("th")
cell
:attr("scope", "row")
:wikitext(index)
tr:node(cell)
-- Append the issue cell.
cell = mw.html.create("td")
cell
:attr("data-sort-value", item.id)
:wikitext(get_wikilink(item, "issue"))
tr:node(cell)
-- Append the published date cell.
cell = mw.html.create("td")
cell:wikitext(humanize_date(item.date))
tr:node(cell)
-- Append content cells.
--{"feature", "interview", "news", "quaility_content"}
-- Append feature and interview cell.
local feature_text = get_wikilink(item, "feature")
local interview_text = get_wikilink(item, "interview")
if interview_text and (interview_text:find("LEFT")) then
cell = mw.html.create("td")
cell:attr("colspan", 2):wikitext(feature_text)
tr:node(cell)
else
cell = mw.html.create("td")
cell:wikitext(feature_text or "—")
tr:node(cell)
cell = mw.html.create("td")
cell:wikitext(interview_text or "—")
tr:node(cell)
end
-- Append news cell.
cell = mw.html.create("td")
cell:wikitext(get_wikilink(item, "news"))
tr:node(cell)
-- Append quaility_content cell.
cell = mw.html.create("td")
cell:wikitext(get_wikilink(item, "quaility_content"))
tr:node(cell)
-- Return the row
return tr
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_table_header_row()
result:node(child)
-- Append the issue rows.
for id, item in ipairs(items) do
child = build_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 column, released_status = args[1], args.status
local item = get_recent_issue(issue_item_data, released_status)
if item then
return get_link_target(item, column)
end
end
--- Retrieve link from the most recent one with the given status.
--- @param args table
--- @return string?
function p._link(args)
local column, released_status = args[1], args.status
local item = get_recent_issue(issue_item_data, released_status)
if item then
return get_wikilink(item, column)
end
end
--- Retrieve content from the most recent one with the given status.
--- @param args table
--- @return string?
function p._content(args)
local released_status = args.status
local item = get_recent_issue(issue_item_data, released_status)
if not item then
return
end
local result = {}
local columns = {"feature", "interview", "news", "quaility_content"}
for _, column in ipairs(columns) do
local link = get_wikilink(item, column, true)
if link and (not link:find("LEFT")) then
table.insert(result, link)
end
end
return table.concat(result, "、")
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