More actions
Content deleted Content added
// via Wikitext Extension for VSCode Tag: Reverted |
// via Wikitext Extension for VSCode Tag: Reverted |
||
Line 80: | Line 80: | ||
if spec.link then tagText = tagText .. '|l=:Category:' .. ucfirst(spec.link) end |
if spec.link then tagText = tagText .. '|l=:Category:' .. ucfirst(spec.link) end |
||
if opts and opts.transparent == '1' then tagText = tagText .. '|o=1' end |
if opts and opts.transparent == '1' then tagText = tagText .. '|o=1' end |
||
tagText = tagText .. '|class=' .. scope .. '-tagged |
tagText = tagText .. '|class=' .. scope .. '-tagged ' .. tagText ..'}}' |
||
-- Category tokens |
-- Category tokens |
Revision as of 07:35, 18 August 2025
Documentation for this module may be created at Module:TagBuilder/doc
-- Module:TagBuilder
local TagParser = require('Module:TagParser')
local B = {}
local function normalizeModuleName(name)
if not name or name == '' then return 'Module:TagCreatures' end
if mw.ustring.find(name, '^Module:') then return name end
return 'Module:' .. name
end
local function ucfirst(s)
return mw.getContentLanguage():ucfirst(s or '')
end
-- Decide if we should include categories, based on |name= and |ns=
local function shouldAddCategories(opts)
local title = mw.title.getCurrentTitle()
local page = title.text or ''
local nsNow = title.nsText or ''
local okName = true
if opts and opts.name and opts.name ~= '' then
local want = mw.text.trim(opts.name)
okName = (want == page) or (want == "''" .. page .. "''")
end
local okNs = true
if opts and opts.ns and opts.ns ~= '' then
okNs = (mw.text.trim(opts.ns) == nsNow)
end
return okName and okNs
end
-- Find a tag spec by key, either under a specific scope or across all top-level tables
local function findTagSpec(data, key, scope)
if scope then
local tbl = data[scope]
if type(tbl) == 'table' then return tbl[key] end
return nil
end
for k, v in pairs(data) do
if type(v) == 'table' and v[key] then
return v[key], k
end
end
return nil
end
-- Recursively expand a key into tag wikitext and categories.
local function expandKey(key, data, scope, opts, seen)
seen = seen or {}
if seen[key] then return '', {} end
seen[key] = true
local spec = findTagSpec(data, key, scope)
-- Unknown key → "Key."
if not spec then
local txt = ucfirst(key)
if txt ~= '' and txt:sub(-1) ~= '.' then txt = txt .. '.' end
return txt, {}
end
-- Composite tag?
if spec.tags then
local out, cats = {}, {}
for _, sub in ipairs(spec.tags) do
local t, c = expandKey(sub, data, scope, opts, seen)
table.insert(out, t)
for _, cc in ipairs(c) do table.insert(cats, cc) end
end
return table.concat(out), cats
end
-- Build {{Tag|...}}
local tagText = string.format('{{Tag|%s', ucfirst(spec.text))
if spec.symbol then tagText = tagText .. '|' .. spec.symbol end
if spec.link then tagText = tagText .. '|l=:Category:' .. ucfirst(spec.link) end
if opts and opts.transparent == '1' then tagText = tagText .. '|o=1' end
tagText = tagText .. '|class=' .. scope .. '-tagged ' .. tagText ..'}}'
-- Category tokens
local cats = {}
if spec.link then
table.insert(cats, '[[Category:' .. ucfirst(spec.link) .. ']]')
end
return tagText, cats
end
-- Core builder: keys (array of strings) → concatenated tags, concatenated categories (conditionally)
function B.buildFromKeys(keys, dataModuleName, scope, opts)
local moduleName = normalizeModuleName(dataModuleName)
local data = mw.loadData(moduleName)
local out, cats, seen = {}, {}, {}
for _, key in ipairs(keys or {}) do
local t, c = expandKey(key, data, scope, opts, seen)
if t and t ~= '' then table.insert(out, t) end
for _, cc in ipairs(c) do table.insert(cats, cc) end
end
-- Apply the |name= / |ns= gate for categories
if not shouldAddCategories(opts) then
cats = {}
end
return table.concat(out), table.concat(cats)
end
-- Convenience: raw ";;" string → tags, cats
function B.build(raw, dataModuleName, scope, opts)
local keys = TagParser.parseList(raw)
return B.buildFromKeys(keys, dataModuleName, scope, opts)
end
---------------------------
-- #invoke entrypoints
---------------------------
local p = {}
-- {{#invoke:TagBuilder|tags|t=undead;; skeletal;;|data=TagCreatures|scope=traits|o=1}}
function p.tags(frame)
local args = frame.args or {}
local t = args.t or args[1] or ''
local data = args.data or 'TagCreatures'
local scope = args.scope -- optional (e.g., "traits")
local opts = {
transparent = args.o or args.transparent,
name = args.name,
ns = args.ns,
}
local tags = B.build(t, data, scope, opts)
return frame:preprocess(tags or '')
end
-- {{#invoke:TagBuilder|categories|t=...|data=TagCreatures|scope=traits|name=Page Name|ns=Creature}}
function p.categories(frame)
local args = frame.args or {}
local t = args.t or args[1] or ''
local data = args.data or 'TagCreatures'
local scope = args.scope
local opts = {
name = args.name,
ns = args.ns,
}
local _, cats = B.build(t, data, scope, opts)
return cats or ''
end
-- For other modules: require('Module:TagBuilder').build(...)
return setmetatable(p, { __index = B })