Модуль:Песочница/Pok: различия между версиями
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) мНет описания правки |
||
| (не показано 426 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
local p = {} | local p = {} | ||
local function trim(s) | |||
local function | if not s then return s end | ||
return | return (s:gsub('^%s*(.-)%s*$', '%1')) | ||
end | end | ||
local function strip_trailing_digits(s) | |||
local function | return s:gsub('%d+$', '') | ||
for | end | ||
if | |||
local function split_first_underscore(k) | |||
local a, b = k:match('^([^_]+)_(.+)$') | |||
return a, b | |||
end | |||
local function collect_labels_from_args(args) | |||
local meta = {} | |||
local seen = {} | |||
for k, v in pairs(args) do | |||
if type(k) == 'string' and k:find('_', 1, true) then | |||
local base, rem = split_first_underscore(k) | |||
if base and rem then | |||
local label = strip_trailing_digits(rem) | |||
label = trim(label) | |||
if label ~= '' then | |||
meta[base] = meta[base] or {} | |||
if not seen[base] then seen[base] = {} end | |||
if not seen[base][label] then | |||
table.insert(meta[base], label) | |||
seen[base][label] = true | |||
end | |||
end | |||
end | |||
end | end | ||
end | end | ||
return | return meta | ||
end | end | ||
function | local function render_from_args(args) | ||
local | local field = args[1] or args.field or args["field"] | ||
local | local label = args[2] or args.label or args["label"] | ||
field = field and trim(field) or '' | |||
label = label and trim(label) or '' | |||
-- | -- map base -> label -> value | ||
local | local map = {} | ||
for k, v in pairs(args) do | |||
if type(k) == 'string' and k:find('_', 1, true) then | |||
local base, rem = split_first_underscore(k) | |||
if base and rem then | |||
local lab = strip_trailing_digits(rem) | |||
lab = trim(lab) | |||
map[base] = map[base] or {} | |||
local cur = map[base][lab] | |||
if cur then | |||
map[base][lab] = cur .. '\n' .. tostring(v) | |||
else | |||
map[base][lab] = tostring(v) | |||
end | |||
end | |||
end | |||
end | end | ||
if field ~= '' and label ~= '' then | |||
local base = map[field] | |||
if base then return base[label] or '' end | |||
return '' | |||
end | |||
if args[1] and args[2] then | |||
if | local f = trim(args[1]); local l = trim(args[2]) | ||
local | local base = map[f] | ||
if base then return base[l] or '' end | |||
if | |||
end | end | ||
return '' | |||
end | |||
function p.main(frame) | |||
local | local args = frame.args or {} | ||
local has_any = false | |||
for k, _ in pairs(args) do | |||
has_any = true; break | |||
end | |||
if not has_any then return collect_labels_from_args(args) end | |||
return | return render_from_args(args) | ||
end | end | ||
return p | return p | ||