Module:ListUtils: Difference between revisions
No edit summary |
No edit summary |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 4: | Line 4: | ||
-- Helper: trim whitespace | -- Helper: trim whitespace | ||
local function trim(s) | local function trim(s) | ||
if not s then return '' end | |||
return (mw.ustring.gsub(s, '^%s*(.-)%s*$', '%1')) | |||
end | end | ||
-- Helper: is already a wikilink like [[Foo]] or [[Foo|Bar]] | -- Helper: is already a wikilink like [[Foo]] or [[Foo|Bar]] | ||
local function isLinked(s) | local function isLinked(s) | ||
return mw.ustring.match(s, '%[%[') ~= nil | |||
end | end | ||
-- Helper: strip existing [[...]] to normalize before relinking | -- Helper: strip existing [[...]] to normalize before relinking | ||
local function stripLinks(s) | local function stripLinks(s) | ||
s = mw.ustring.gsub(s, '%[%[', '') | |||
s = mw.ustring.gsub(s, '%]%]', '') | |||
return s | |||
end | end | ||
-- Public: turn "A, B , [[C|X]] , D" into "[[A]], [[B]], [[C|X]], [[D]]" | -- Public: turn "A, B , [[C|X]] , D" into "[[A]], [[B]], [[C|X]], [[D]]" | ||
function p.linkifyCommaList(frame) | function p.linkifyCommaList(frame) | ||
local raw = frame.args[1] or '' | |||
raw = trim(raw) | |||
if raw == '' then return '' end | |||
-- Split on commas (allowing messy spacing) | |||
local parts = mw.text.split(raw, ',') | |||
local out = {} | |||
local seen = {} | |||
for _, part in ipairs(parts) do | |||
local s = trim(part) | |||
if s ~= '' then | |||
-- Keep already-linked entries as-is | |||
if isLinked(s) then | |||
if not seen[s] then | |||
table.insert(out, s) | |||
seen[s] = true | |||
end | |||
else | |||
-- Normalize any accidental brackets then relink | |||
local plain = stripLinks(s) | |||
plain = trim(plain) | |||
-- Deduplicate by plain text | |||
if not seen[plain] then | |||
table.insert(out, '[[' .. plain .. ']]') | |||
seen[plain] = true | |||
end | |||
end | |||
end | |||
end | |||
return table.concat(out, ', ') | |||
end | end | ||
-- | -------------------------------------------------------------------- | ||
-- | -- Generic helper for comma lists → categories + SMW properties | ||
function | -------------------------------------------------------------------- | ||
-- Internal helper: works on raw strings | |||
if | local function catsAndPropsFromList(list, property, catNs) | ||
list = trim(list or '') | |||
if list == '' then | |||
return '' | return '' | ||
end | end | ||
local parts = mw.text.split( | catNs = catNs or 'Category' | ||
local parts = mw.text.split(list, ',') | |||
local out = {} | local out = {} | ||
local seen = {} | local seen = {} | ||
| Line 79: | Line 83: | ||
if plain ~= '' and not seen[plain] then | if plain ~= '' and not seen[plain] then | ||
table.insert(out, '[[ | -- Category link (optional if catNs ~= '') | ||
table.insert(out, '[[ | if catNs ~= '' then | ||
table.insert(out, '[[' .. catNs .. ':' .. plain .. ']]') | |||
end | |||
-- Property annotation (hidden label so nothing shows) | |||
if property and property ~= '' then | |||
table.insert(out, '[[' .. property .. '::' .. plain .. '| ]]') | |||
end | |||
seen[plain] = true | seen[plain] = true | ||
end | end | ||
| Line 87: | Line 97: | ||
return table.concat(out, ' ') | return table.concat(out, ' ') | ||
end | |||
-- Internal: props only | |||
local function propsFromList(list, property) | |||
list = trim(list or '') | |||
if list == '' or not property or property == '' then | |||
return '' | |||
end | |||
local parts = mw.text.split(list, ',') | |||
local out = {} | |||
local seen = {} | |||
for _, part in ipairs(parts) do | |||
local s = trim(part) | |||
if s ~= '' then | |||
local plain = stripLinks(s) | |||
plain = mw.ustring.match(plain, '([^|]+)') or plain | |||
plain = trim(plain) | |||
if plain ~= '' and not seen[plain] then | |||
table.insert(out, '[[' .. property .. '::' .. plain .. '| ]]') | |||
seen[plain] = true | |||
end | |||
end | |||
end | |||
return table.concat(out, ' ') | |||
end | |||
-- Public: generic #invoke entry point | |||
-- Examples: | |||
-- {{#invoke:ListUtils|catsAndProps|Environment, Energy|HasVertical}} | |||
-- {{#invoke:ListUtils|catsAndProps | |||
-- | list = Environment, Energy | |||
-- | property = HasVertical | |||
-- | catns = Category | |||
-- }} | |||
function p.catsAndProps(frame) | |||
local list = frame.args.list or frame.args[1] or '' | |||
local property = frame.args.property or frame.args[2] or '' | |||
local catNs = frame.args.catns or frame.args.categoryNamespace or frame.args[3] or 'Category' | |||
return catsAndPropsFromList(list, property, catNs) | |||
end | |||
-- Public: props-only entry point | |||
-- {{#invoke:ListUtils|propsOnly|A, B, C|HasThing}} | |||
-- {{#invoke:ListUtils|propsOnly|list=A, B, C|property=HasThing}} | |||
function p.propsOnly(frame) | |||
local list = frame.args.list or frame.args[1] or '' | |||
local property = frame.args.property or frame.args[2] or '' | |||
return propsFromList(list, property) | |||
end | end | ||
return p | return p | ||