Module:Format TemplateData/global
local Export = {
item = 51435481,
serial = "2020-08-01",
subpages = "TemplateData",
suffix = "tab",
suite = "TemplateDataGlobal"
}
--[=[
Retrieve TemplateData from Commons:Data (or other global source).
require()
Inspired by [[de:User:Yurik]].
]=]
local Failsafe = Export
local failsafe = function(atleast)
-- Retrieve versioning and check for compliance.
-- Precondition:
-- atleast -- string, with required version
-- or "wikidata" or "~" or "@" or false
-- Postcondition:
-- Returns string -- with queried version/item, also if problem
-- false -- if appropriate
local last = (atleast == "~")
local link = (atleast == "@")
local since = atleast
local r
if last or link or since == "wikidata" then
local item = Failsafe.item
since = false
if type(item) == "number" and item > 0 then
local suited = string.format("Q%d", item)
local entity = mw.wikibase.getEntity(suited)
if type(entity) == "table" then
local seek = Failsafe.serialProperty or "P348"
local vsn = entity:formatPropertyValues(seek)
if type(vsn) == "table" and type(vsn.value) == "string" and vsn.value ~= "" then
if last and vsn.value == Failsafe.serial then
r = false
elseif link then
if mw.title.getCurrentTitle().prefixedText == mw.wikibase.getSitelink(suited) then
r = false
else
r = suited
end
else
r = vsn.value
end
end
end
end
end
if type(r) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial
else
r = false
end
end
return r
end -- failsafe()
local function fair(already, adapt, append)
-- Merge local definitions into global base.
-- Parameter:
-- already -- global item
-- adapt -- local override item
-- append -- append to sequence table
-- Returns merged item
local r
if already and adapt then
if type(already) == "table" and type(adapt) == "table" then
r = already
if append then
for i = 1, #adapt do
table.insert(r, adapt[i])
end -- for i
else
for k, v in pairs(adapt) do
r[k] = v
end -- for k, v
end
else
r = adapt
end
else
r = already or adapt
end
return r
end -- fair()
local function feed(apply)
-- Retrieve override from JSON code.
-- Parameter:
-- apply -- string, with JSON
-- Returns string, with error message, or table
local lucky, r = pcall(mw.text.jsonDecode, apply)
if not lucky then
r = "fatal JSON error in LOCAL override"
end
return r
end -- feed()
local function find(access)
-- Fetch data from page.
-- Parameter:
-- access -- string, with core page name
-- Returns
-- 1. string, with prefixed page name
-- 2. table with JSON data, or error message
local storage = access
local lucky, r
if Export.suffix and not storage:find(".", 2, true) then
local k = -1 - #Export.suffix
if storage:sub(k) ~= "." .. Export.suffix then
storage = string.format("%s.%s", storage, Export.suffix)
end
end
if Export.subpages and not storage:find("/", 1, true) then
storage = string.format("%s/%s", Export.subpages, storage)
end
lucky, r = pcall(mw.ext.data.get, storage, "_")
storage = "Data:" .. storage
if mw.site.siteName ~= "Wikimedia Commons" then
storage = "commons:" .. storage
end
if type(r) ~= "table" and type(r) ~= "string" then
r = "INVALID"
end
return storage, r
end -- find()
local function flat(apply)
-- Convert tabular data into TemplateData.
-- Parameter:
-- apply -- table, with tabular data
-- Returns string, with error message, or table, with TemplateData
local r, scream
local function failed(at, alert)
if scream then
scream = string.format("%s * #%d: %s", scream, at, alert)
else
scream = add
end
end -- failed()
if type(apply.schema) == "table" and type(apply.schema.fields) == "table" and type(apply.data) == "table" then
local order = {}
local entry, got, params, parOrder, s, sign, td, v
for k, v in pairs(apply.schema.fields) do
if type(v) == "table" then
table.insert(order, v.name)
end
end -- for k, v
for i = 1, #apply.data do
entry = apply.data[i]
if type(entry) == "table" then
got = {}
sign = false
for j = 1, #entry do
s = order[j]
v = entry[j]
if type(v) == "string" then
v = mw.text.trim(v)
if v == "" then
v = false
end
end
if v then
if s == "name" then
sign = v
elseif s == "aliases" then
if type(v) == "string" then
got.aliases = mw.text.split(v, "%s*|%s*")
else
failed(i, "aliases not a string")
end
else
got[s] = v
end
end
end -- for j
if sign == "|" then
if td then
failed(i, "root repeated")
else
td = {description = got.description}
if type(got.type) == "string" then
td.format = got.type:gsub("N", "\n")
end
end
elseif sign then
if params then
if params[sign] then
failed(i, "name repeated: " .. sign)
end
else
params = {}
parOrder = {}
end
params[sign] = got
table.insert(parOrder, sign)
else
failed(i, "missing name")
end
else
failed(i, "invalid component")
end
end -- for i
r = td or {}
r.params = params
r.paramOrder = parOrder
else
r = "bad tabular structure"
end
return scream or r or "EMPTY"
end -- flat()
local function flush(assembly, avoid)
-- Remove element from sequence table.
-- Parameter:
-- assembly -- sequence table
-- avoid -- element
for i = 1, #assembly do
if assembly[i] == avoid then
table.remove(assembly, i)
break -- for i
end
end -- for i
end -- flush()
local function fold(already, adapt)
-- Merge local parameter definitions into global base.
-- Parameter:
-- already -- table, with global data
-- adapt -- sequence table, with local params overrides
-- Returns string, with error message, or table, with TemplateData
local order = {}
local params = {}
local r = already
local entry, override, s
r.params = r.params or {}
r.paramOrder = r.paramOrder or {}
for i = 1, #adapt do
override = adapt[i]
if type(override) ~= "table" then
r = string.format("No object at LOCAL params[%d]", i)
break -- for i
elseif type(override.global) == "string" then
s = override.global
entry = r.params[s]
if type(entry) == "table" then
flush(r.paramOrder, s)
if type(override["local"]) == "string" then
s = override["local"]
override["local"] = nil
elseif override["local"] == false then
entry = nil
end
if entry then
override.global = nil
for k, v in pairs(override) do
entry[k] = fair(entry[k], override[k], (k == "aliases"))
end -- for k, v
table.insert(order, s)
end
params[s] = entry
else
r = string.format("No GLOBAL params %s for LOCAL [%d]", s, i)
break -- for i
end
elseif type(override["local"]) == "string" then
s = override["local"]
override["local"] = nil
params[s] = override
table.insert(order, s)
else
r = string.format("No name for LOCAL params[%d]", i)
break -- for i
end
end -- for i
if type(r) == "table" then
for i = 1, #r.paramOrder do
s = r.paramOrder[i]
params[s] = r.params[s]
table.insert(order, s)
end -- for i
r.params = params
r.paramOrder = order
end
return r
end -- fold()
local function fork(already, adapt)
-- Merge local definitions into global base.
-- Parameter:
-- already -- table, with global data
-- adapt -- table, with local overrides
-- Returns string, with error message, or table, with TemplateData
local root = {"description", "format", "maps", "sets", "style"}
local r = already
for k, v in pairs(root) do
if adapt[v] then
r[v] = fair(r[v], adapt[v])
end
end -- for k, v
if type(adapt.params) == "table" then
r = fold(r, adapt.params)
end
return r
end -- fork()
local function furnish(apply, at, adapt)
-- Convert external data into TemplateData.
-- Parameter:
-- apply -- table, with external data
-- at -- string, with page name
-- adapt -- JSON string or table or not, with local overrides
-- Returns string, with error message, or table, with TemplateData
local r
if at:sub(-4) == ".tab" then
r = flat(apply)
else
r = "Unknown page format: " .. at
end
if adapt and type(r) == "table" then
local override = adapt
if type(adapt) == "string" then
override = feed(adapt)
if type(override) == "string" then
r = override
end
end
if type(override) == "table" then
r = fork(r, override)
end
end
return r
end -- furnish()
Export.failsafe = function(frame)
-- Versioning interface.
local s = type(frame)
local since
if s == "table" then
since = frame.args[1]
elseif s == "string" then
since = frame
end
if since then
since = mw.text.trim(since)
if since == "" then
since = false
end
end
return failsafe(since) or ""
end -- Export.failsafe()
Export.fetch = function(access, adapt)
-- Fetch data from site.
-- Parameter:
-- access -- string, with page specification
-- adapt -- JSON string or table or not, with local overrides
-- Returns
-- 1. string, with error message or prefixed page name
-- 2. table with TemplateData, or not
local storage, t = find(access)
local s
if type(t) == "table" then
t = furnish(t, storage, adapt)
if type(t) ~= "table" then
s = t
end
else
s = t
end
if type(t) ~= "table" then
storage = string.format("[[%s]]", storage)
if s then
storage = string.format("%s * %s", storage, s)
end
t = false
end
return storage, t
end -- Export.fetch()
return Export
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.