模組:沙盒/Lopullinen
外观
测试区
[编辑]{{#invoke:沙盒/Lopullinen|target}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|target|2020-01}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|link}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|link|upcoming}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|toc}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|toc|2022-01|style=inline}}
⇒ package.lua第80行Lua错误:module 'Module:Current VGNL/items' not found{{#invoke:沙盒/Lopullinen|index}}
⇒ 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 if an item exists 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 based on a 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 a copy of it.
--- @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 into a string.
--- For example: `{2024, 07}` becomes "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 an issue ID string into an ID tuple.
--- For example: "2024-07" becomes `{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 tuple into a Chinese date string.
--- For example: `{2025, 3, 25}` becomes "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
--- Convert an issue's release date into a string, including the status
--- type.
--- @param val DATE | boolean | nil
--- @return string
local function get_index_date_str(val)
if type(val) == "table" then
return format_date(val)
end
if val == nil then
return "(編輯中)"
end
if val == false then
return "(未出刊)"
end
return "(未知狀態)"
end
--- Retrieve the first issue by its ID or status.
--- @param items ISSUE_ITEMS
--- @param id
--- | string # e.g. "2024-01"
--- | "released" # the most recently released issue
--- | "upcoming" # the next upcoming issue
--- | nil # defaults to "released"
--- @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 an issue's 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
--- Get the column title for use in the index page.
--- @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
--- Get the column title for use in a content environment.
--- @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
--- I bet five cents that you wouldn't understand my docstrings if I
--- wrote it.
--- @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 for the index table.
--- @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 other 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 table cell for an issue row in the index table.
--- @param item ISSUE_ITEM
--- @param column COLUMN_NAME?
--- @return table<string, any>
local function _build_index_table_issue_cell(item, column)
local text
local display = get_index_text(item, column)
if display == nil then
text = "—"
else
local target = get_link_target(item, column)
text = build_linked_text(target, display)
end
return mw.html.create("td"):wikitext(text)
end
--- Build the content row for an issue in the index table.
--- @param index number
--- @param item ISSUE_ITEM
--- @return table<string, any>
local function _build_index_table_issue_row(index, item)
local build_cell = _build_index_table_issue_cell
local row, cell = mw.html.create("tr"), nil
-- Append the row header cell.
cell = mw.html.create("th")
cell:attr("scope", "row"):wikitext(index)
row:node(cell)
-- Append the issue cell.
cell = build_cell(item)
row:node(cell)
-- Append the published date cell.
cell = mw.html.create("td")
cell:wikitext(get_index_date_str(item.date))
row:node(cell)
-- Append feature and interview cell.
if get_index_text(item, "interview") == "LEFT" then
-- Append the spanning feature cell.
cell = build_cell(item, "feature"):attr("colspan", 2)
row:node(cell)
else
-- Append the feature cell.
cell = build_cell(item, "feature")
row:node(cell)
-- Append the interview cell.
cell = build_cell(item, "interview")
row:node(cell)
end
-- Append the news cell.
cell = build_cell(item, "news")
row:node(cell)
-- Append the quaility content cell.
cell = build_cell(item, "quaility_content")
row:node(cell)
-- Return the row
return row
end
--- Build and return the index table in wikitext format.
--- @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 the given
--- arguments.
--- @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 the link target from the most recent issue 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 the linked text from the most recent issue 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 the content from the most recent issue 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 table in wikitext format.
--- @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