|
|
| (не показаны 52 промежуточные версии этого же участника) |
| Строка 1: |
Строка 1: |
| local p = {} | | local p = {} |
| | local getArgs = require('Module:Arguments').getArgs |
|
| |
|
| local function split(s, sep)
| | function p.main(frame) |
| if s == nil then return {} end
| | local args = getArgs(frame, { removeBlanks = false }) |
| local parts = {}
| | local name = args[1] or "" |
| sep = sep or "%."
| | local attributes = args[2] or "" |
| for part in string.gmatch(s, "([^" .. sep .. "]+)") do
| | if name == "" then |
| table.insert(parts, part)
| | return "<span class=\"error\">Ошибка: не указано имя файла.</span>" |
| end
| | end |
| return parts
| | local ext = (args["ext"] or "png"):gsub("^%.", "") |
| end
| | local namespace = args["namespace"] or "Файл" |
| | local max = tonumber(args["max"]) or 50 |
| | local include_base = (args["base"] ~= "no") |
|
| |
|
| local function parse_indexed_part(part) | | local found = {} |
| -- supports "key", "key[1]" and numeric "1" forms
| |
| local key, idx = string.match(part, "^(.-)%[(%d+)%]$")
| |
| if key then
| |
| return key, tonumber(idx)
| |
| end
| |
| -- numeric-only part (array index)
| |
| local num = tonumber(part)
| |
| if num then
| |
| return nil, num
| |
| end
| |
| return part, nil
| |
| end
| |
|
| |
|
| local function get_by_path(tbl, path)
| | if include_base then |
| if not tbl then return nil end
| | local t = mw.title.new("Файл:" .. name .. "." .. ext) |
| local parts = split(path, "%.")
| | if t and t.exists then |
| local cur = tbl
| | table.insert(found, "") |
| for _, part in ipairs(parts) do
| | end |
| local key, idx = parse_indexed_part(part)
| | end |
| if key and key ~= "" then
| |
| cur = cur[key]
| |
| end
| |
| if idx then
| |
| -- Lua tables from mw.loadData are 1-based for arrays, so we use the index directly.
| |
| if type(cur) ~= "table" then
| |
| return nil
| |
| end
| |
| cur = cur[idx]
| |
| end
| |
| if cur == nil then
| |
| return nil
| |
| end
| |
| end
| |
| return cur
| |
| end | |
|
| |
|
| local function is_array(t) | | for i = 1, max do |
| if type(t) ~= "table" then return false end
| | local t = mw.title.new("Файл:" .. name .. "-" .. i .. "." .. ext) |
| local i = 0
| | if t and t.exists then |
| for _ in pairs(t) do
| | table.insert(found, "-" .. i) |
| i = i + 1
| | end |
| -- if any key is not a number then not a pure array
| | end |
| end
| |
| -- We'll treat table as array if all keys are numeric 1..n
| |
| local n = 0
| |
| for k in pairs(t) do
| |
| if type(k) ~= "number" then
| |
| return false
| |
| end
| |
| if k > n then n = k end
| |
| end
| |
| return n > 0
| |
| end | |
|
| |
|
| local function format_value(v)
| | if #found == 0 then |
| if v == nil then return "" end
| | return "" |
| local t = type(v)
| | end |
| if t == "string" or t == "number" or t == "boolean" then
| |
| return tostring(v)
| |
| elseif t == "table" then
| |
| -- array-like: join with commas
| |
| if is_array(v) then
| |
| local out = {}
| |
| local max = 0
| |
| for k in pairs(v) do if type(k) == "number" and k > max then max = k end end
| |
| for i = 1, max do
| |
| table.insert(out, format_value(v[i]))
| |
| end
| |
| return table.concat(out, ", ")
| |
| else
| |
| -- associative table: "k: v" pairs joined by ", "
| |
| local out = {}
| |
| for k, val in pairs(v) do
| |
| table.insert(out, tostring(k) .. ": " .. format_value(val))
| |
| end
| |
| return table.concat(out, ", ")
| |
| end
| |
| else
| |
| return tostring(v)
| |
| end
| |
| end | |
|
| |
|
| -- Public entry point for invocation
| | local before = "[[" .. namespace .. ":" .. name |
| function p.get(frame)
| | local after = "." .. ext .. "|" .. attributes .. "]]" |
| local args = frame.args or {}
| |
| local id = args[1] or ""
| |
| local pagePath = args[2] or ""
| |
| local keyPath = args[3] or ""
| |
|
| |
|
| -- Build module load path. The user requested appending to User:IanComradeBot/
| | local parts = {} |
| local baseUser = "User:IanComradeBot/"
| | table.insert(parts, "<choose before=\"" .. before .. "\" after=\"" .. after .. "\">") |
| local moduleName = "Module:" .. baseUser .. pagePath .. "/data"
| | for _, suf in ipairs(found) do |
| | table.insert(parts, "<option>" .. suf .. "</option>") |
| | end |
| | table.insert(parts, "</choose>") |
|
| |
|
| -- Try load
| | return frame:preprocess(table.concat(parts, "\n")) |
| local ok, data = pcall(mw.loadData, moduleName)
| |
| if not ok or not data then
| |
| -- Fallback: try using pagePath directly as a Module name (in case the caller passed full path)
| |
| local altModuleName = "Module:" .. pagePath .. "/data"
| |
| ok, data = pcall(mw.loadData, altModuleName)
| |
| if not ok or not data then
| |
| return ""
| |
| end
| |
| end
| |
| | |
| -- Find by id, fallback to default
| |
| local entry = nil
| |
| if id ~= "" then
| |
| entry = data[id]
| |
| end
| |
| if entry == nil then
| |
| entry = data["default"]
| |
| end
| |
| if entry == nil then
| |
| return ""
| |
| end
| |
| | |
| if keyPath == "" then
| |
| -- If no keyPath provided, return formatted entire entry
| |
| return format_value(entry)
| |
| end
| |
| | |
| local value = get_by_path(entry, keyPath)
| |
| return format_value(value)
| |
| end | | end |
|
| |
|
| return p | | return p |