Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:C: Difference between revisions

From Teriock
Content deleted Content added
// via Wikitext Extension for VSCode
// via Wikitext Extension for VSCode
Line 1: Line 1:
local p = {}

local p = {}
local p = {}


local function makeBar(frame, title, content, link, flags, bottom)
local function makeBar(frame, title, content, link, flags, bottom)
-- ... (unchanged)
if content == '' then return '' end
local barSpace = mw.html.create('span')
barSpace:wikitext(frame:preprocess(' ')):css('display', 'none')
local barTitle = mw.html.create('span')
local barTitleClass = "{{lc:" .. title .. "}}"
barTitleClass = barTitleClass:gsub(' ', '-')
barTitleClass = barTitleClass:gsub('\'', '')
barTitleClass = barTitleClass:gsub('\"', '')
local barText = "{{ucfirst:" .. title .. "}}"
if link then barText = "[[" .. link .. "|" .. barText .. "]]" end
barText = barText .. ":"
barTitle:addClass('ability-bar-title'):wikitext(frame:preprocess(barText))
:css('font-weight', 'bold'):css('margin-right', '0.5em')
local barContent = mw.html.create('span')
barContent:addClass('ability-bar-content'):wikitext(content)
local output = mw.html.create('div')
if bottom then output = mw.html.create('span') end
if not flags then flags = {} end
for k, v in pairs(flags) do
if type(v) == 'string' then
output:addClass('flag-' .. k .. '-' .. v)
end
end
output:addClass('ability-bar'):addClass('ability-bar-' .. barTitleClass)
:attr(flags):attr('test', 'out'):node(barSpace):node(barTitle):node(
barSpace):node(barContent):css('display', 'block')
-- if flags then
-- for k, v in ipairs(flags) do
-- output:attr(k, v)
-- end
-- end
return tostring(output)
end
end


-- === NEW: shared abilities parsing helpers ===
function p.c(frame)
local function parseAbilitiesString(abilitiesString)
local args = frame.args
local rawAbilities = args['a'] or ''

-- === TAGS & CATEGORIES via TagBuilder ===
local TagBuilder = require('Module:TagBuilder')
local tRaw = args['t'] or ''
local looks = args['l'] or ''
local name = args['name'] or ''
local baseHp = args['hp'] or '1'
local baseMp = args['mp'] or '1'
local size = args['size'] or '3'
local int = args['int'] or '0'
local str = args['str'] or '0'
local mov = args['mov'] or '0'
local snk = args['snk'] or '0'
local per = args['per'] or '0'
local preAbilities = ''
if (int == '0') then
preAbilities = preAbilities .. "Normal Intelligence;; "
end
if (str == '0') then preAbilities = preAbilities .. "Normal Strength;; " end
if (mov == '0') then preAbilities = preAbilities .. "Normal Movement;; " end
if (snk == '0') then preAbilities = preAbilities .. "Normal Sneak;; " end
if (per == '0') then
preAbilities = preAbilities .. "Normal Perception;; "
end
local abilitiesString = preAbilities .. rawAbilities
local opts = {
name = name,
ns = 'Creature', -- gate categories to the Creature namespace
transparent = args.o or args.transparent -- optional passthrough
}
-- Use TagCreatures data and traits scope
local tagOut, catOut =
TagBuilder.build(tRaw, 'TagCreatures', 'traits', opts)

-- === Parse abilities into a structured table ===
local abilities = {}
local abilities = {}
for ability in mw.text.gsplit(abilitiesString, ";;", true) do
for ability in mw.text.gsplit(abilitiesString or '', ";;", true) do
ability = mw.text.trim(ability)
ability = mw.text.trim(ability)
if ability ~= "" then
if ability ~= "" then
Line 87: Line 22:


-- notes (order-insensitive, tolerate any following marker)
-- notes (order-insensitive, tolerate any following marker)
local limitedMatch = mw.ustring.match(ability,
local limitedMatch = mw.ustring.match(ability, "%-l%-(.-)(%-[liag]%-|$)")
"%-l%-(.-)(%-[liag]%-|$)") or
or mw.ustring.match(ability, "%-l%-(.+)$")
mw.ustring.match(ability, "%-l%-(.+)$")
if limitedMatch then limited = mw.text.trim(limitedMatch) end
if limitedMatch then limited = mw.text.trim(limitedMatch) end


local improvedMatch = mw.ustring.match(ability,
local improvedMatch = mw.ustring.match(ability, "%-i%-(.-)(%-[liag]%-|$)")
"%-i%-(.-)(%-[liag]%-|$)") or
or mw.ustring.match(ability, "%-i%-(.+)$")
mw.ustring.match(ability, "%-i%-(.+)$")
if improvedMatch then improved = mw.text.trim(improvedMatch) end
if improvedMatch then
improved = mw.text.trim(improvedMatch)
end


-- clean name (strip markers + their payloads/flags)
-- clean name (strip markers + payloads/flags)
name = mw.ustring.gsub(name, "%-l%-.+", "")
name = mw.ustring.gsub(name, "%-l%-.+", "")
name = mw.ustring.gsub(name, "%-i%-.+", "")
name = mw.ustring.gsub(name, "%-i%-.+", "")
Line 116: Line 47:
end
end


-- Sort alphabetically by name (stable)
table.sort(abilities, function(a, b) return a.name < b.name end)
table.sort(abilities, function(a, b) return a.name < b.name end)
return abilities
end


local function buildAETransclusions(abilities)
-- Build the out string (NO visible separators between AE templates)
local transclusions = {}
local transclusions = {}
for _, a in ipairs(abilities) do
for _, a in ipairs(abilities or {}) do
local t = {"{{AE|", a.name}
local t = {"{{AE|", a.name}
if a.limited ~= "" then table.insert(t, "|limited=" .. a.limited) end
if a.limited ~= "" then table.insert(t, "|limited=" .. a.limited) end
if a.improved ~= "" then
if a.improved ~= "" then table.insert(t, "|improved=" .. a.improved) end
table.insert(t, "|improved=" .. a.improved)
end
if a.gifted then table.insert(t, "|gifted=1") end
if a.gifted then table.insert(t, "|gifted=1") end
if a.adept then table.insert(t, "|adept=1") end
if a.adept then table.insert(t, "|adept=1") end
table.insert(t, "}}")
table.insert(t, "}}")
table.insert(transclusions, table.concat(t))
table.insert(transclusions, table.concat(t))
end
end
-- no visible separators between AE templates
return table.concat(transclusions, "")
end
-- === END helpers ===


function p.c(frame)
-- Use "" (or "\n") so no semicolons are emitted
local inner = table.concat(transclusions, "") -- <- no separators
local args = frame.args
local rawAbilities = args['a'] or ''


-- === TAGS & CATEGORIES via TagBuilder ===
local categoryString = ''
local TagBuilder = require('Module:TagBuilder')
local tRaw = args['t'] or ''
local looks = args['l'] or ''
local name = args['name'] or ''
local baseHp = args['hp'] or '1'
local baseMp = args['mp'] or '1'
local size = args['size'] or '3'
local int = args['int'] or '0'
local str = args['str'] or '0'
local mov = args['mov'] or '0'
local snk = args['snk'] or '0'
local per = args['per'] or '0'


local statContent = ''
local preAbilities = ''
if (int == '0') then preAbilities = preAbilities .. "Normal Intelligence;; " end
statContent =
if (str == '0') then preAbilities = preAbilities .. "Normal Strength;; " end
statContent .. "{{Tag|" .. baseHp .. " HP|❤️|l=:Category:" .. baseHp ..
if (mov == '0') then preAbilities = preAbilities .. "Normal Movement;; " end
" HP creatures|c=#e01b24|class=cost-tagged hp" .. baseHp .. "}}"
if (snk == '0') then preAbilities = preAbilities .. "Normal Sneak;; " end
categoryString = categoryString .. "[[Category:" .. baseHp ..
if (per == '0') then preAbilities = preAbilities .. "Normal Perception;; " end
" HP creatures" .. "]]"

statContent =
local abilitiesString = preAbilities .. rawAbilities
statContent .. "{{Tag|" .. baseMp .. " MP|🩵|l=:Category:" .. baseMp ..
local opts = {
" MP creatures|c=#3584e4|class=cost-tagged hp" .. baseMp .. "}}"
name = name,
categoryString = categoryString .. "[[Category:" .. baseMp ..
ns = 'Creature',
" MP creatures" .. "]]"
transparent = args.o or args.transparent
statContent = statContent .. "{{Tag|Size " .. size ..
}
"|⬆️|l=:Category:Size " .. size ..
local tagOut, catOut = TagBuilder.build(tRaw, 'TagCreatures', 'traits', opts)
" creatures|c=#e4a835|class=size-tagged size" .. size ..

"}}"
-- === Parse and render main abilities with shared helpers ===
categoryString = categoryString .. "[[Category:Size " .. size ..
local abilities = parseAbilitiesString(abilitiesString)
" creatures" .. "]]"
local inner = buildAETransclusions(abilities)

local categoryString = ''


-- (stats/attributes rendering unchanged)
local attributeContent = ''
-- ...
attributeContent = ""
attributeContent = attributeContent .. "{{Tag|" .. int ..
"|INT|l=:Category:INT value of " .. int ..
" creatures}}"
categoryString = categoryString .. "[[Category:INT value of " .. int ..
" creatures]]"
attributeContent = attributeContent .. "{{Tag|" .. str ..
"|STR|l=:Category:STR value of " .. str ..
" creatures}}"
categoryString = categoryString .. "[[Category:STR value of " .. str ..
" creatures]]"
attributeContent = attributeContent .. "{{Tag|" .. mov ..
"|MOV|l=:Category:MOV value of " .. mov ..
" creatures}}"
categoryString = categoryString .. "[[Category:MOV value of " .. mov ..
" creatures]]"
attributeContent = attributeContent .. "{{Tag|" .. snk ..
"|SNK|l=:Category:SNK value of " .. snk ..
" creatures}}"
categoryString = categoryString .. "[[Category:SNK value of " .. snk ..
" creatures]]"
attributeContent = attributeContent .. "{{Tag|" .. per ..
"|PER|l=:Category:PER value of " .. per ..
" creatures}}"
categoryString = categoryString .. "[[Category:PER value of " .. per ..
" creatures]]"


-- Assemble output: tags (visible), abilities, then categories (gated by name/ns)
local out = ""
local out = ""
out = out .. makeBar(frame, "Stats", statContent, nul, nul, false)
out = out .. makeBar(frame, "Stats", statContent, nul, nul, false)
Line 192: Line 116:
if args['lifespan'] then
if args['lifespan'] then
local lifespanText = args['lifespan'] .. " years."
local lifespanText = args['lifespan'] .. " years."
categoryString = categoryString .. "[[Category:" .. args['lifespan'] ..
categoryString = categoryString .. "[[Category:" .. args['lifespan'] .. " year lifespan creatures]]"
" year lifespan creatures]]"
if args['adult'] then
if args['adult'] then
lifespanText = lifespanText .. " Adult at age " .. args['adult'] ..
lifespanText = lifespanText .. " Adult at age " .. args['adult'] .. "."
"."
end
end
out = out .. makeBar(frame, "Lifespan", lifespanText, nul, nul, false)
out = out .. makeBar(frame, "Lifespan", lifespanText, nul, nul, false)
end
end

out = out .. '<hr>'
out = out .. '<hr>'
if args['d'] then out = out .. args['d'] .. '<hr>' end
if args['d'] then out = out .. args['d'] .. '<hr>' end
out = out .. '<div class="expandable-table"><div>' ..
frame:preprocess(inner) .. '</div></div>'
out = out .. (catOut or '')


-- if args['f'] then
-- main abilities block
out = out .. '<div class="expandable-table"><div>' .. frame:preprocess(inner) .. '</div></div>'
-- out = out .. '<hr>'

-- === familiar abilities (args['f']) using the same parsing ===
if args['f'] and mw.text.trim(args['f']) ~= '' then
local fAbilities = parseAbilitiesString(args['f'])
local fInner = buildAETransclusions(fAbilities)
-- You can wrap in a bar or just mirror the main output style; here we label it:
out = out .. makeBar(frame, "Familiar Abilities",
frame:preprocess('<div class="expandable-table"><div>' .. fInner .. '</div></div>'),
nul, nul, false)
end

out = out .. (catOut or '')


local page = mw.title.getCurrentTitle().text
local page = mw.title.getCurrentTitle().text
Line 215: Line 147:
end
end


-- local tt = mw.title.makeTitle("Ability", "Normal Strength")

-- out = out .. tt.categories

-- Preprocess the whole thing so {{Tag}} expands
return frame:preprocess(out)
return frame:preprocess(out)
end
end

Revision as of 22:03, 12 August 2025

Documentation for this module may be created at Module:C/doc

local p = {}

local p = {}

local function makeBar(frame, title, content, link, flags, bottom)
    -- ... (unchanged)
end

-- === NEW: shared abilities parsing helpers ===
local function parseAbilitiesString(abilitiesString)
    local abilities = {}
    for ability in mw.text.gsplit(abilitiesString or '', ";;", true) do
        ability = mw.text.trim(ability)
        if ability ~= "" then
            local name = ability
            local limited, improved = "", ""
            local gifted, adept = false, false

            -- flags
            if mw.ustring.find(ability, "%-g%-") then gifted = true end
            if mw.ustring.find(ability, "%-a%-") then adept = true end

            -- notes (order-insensitive, tolerate any following marker)
            local limitedMatch = mw.ustring.match(ability, "%-l%-(.-)(%-[liag]%-|$)")
                                   or mw.ustring.match(ability, "%-l%-(.+)$")
            if limitedMatch then limited = mw.text.trim(limitedMatch) end

            local improvedMatch = mw.ustring.match(ability, "%-i%-(.-)(%-[liag]%-|$)")
                                    or mw.ustring.match(ability, "%-i%-(.+)$")
            if improvedMatch then improved = mw.text.trim(improvedMatch) end

            -- clean name (strip markers + payloads/flags)
            name = mw.ustring.gsub(name, "%-l%-.+", "")
            name = mw.ustring.gsub(name, "%-i%-.+", "")
            name = mw.ustring.gsub(name, "%-g%-", "")
            name = mw.ustring.gsub(name, "%-a%-", "")
            name = mw.text.trim(name)

            table.insert(abilities, {
                name = name,
                limited = limited,
                improved = improved,
                gifted = gifted,
                adept = adept
            })
        end
    end

    table.sort(abilities, function(a, b) return a.name < b.name end)
    return abilities
end

local function buildAETransclusions(abilities)
    local transclusions = {}
    for _, a in ipairs(abilities or {}) do
        local t = {"{{AE|", a.name}
        if a.limited ~= "" then table.insert(t, "|limited=" .. a.limited) end
        if a.improved ~= "" then table.insert(t, "|improved=" .. a.improved) end
        if a.gifted then table.insert(t, "|gifted=1") end
        if a.adept  then table.insert(t, "|adept=1")  end
        table.insert(t, "}}")
        table.insert(transclusions, table.concat(t))
    end
    -- no visible separators between AE templates
    return table.concat(transclusions, "")
end
-- === END helpers ===

function p.c(frame)
    local args = frame.args
    local rawAbilities = args['a'] or ''

    -- === TAGS & CATEGORIES via TagBuilder ===
    local TagBuilder = require('Module:TagBuilder')
    local tRaw = args['t'] or ''
    local looks = args['l'] or ''
    local name = args['name'] or ''
    local baseHp = args['hp'] or '1'
    local baseMp = args['mp'] or '1'
    local size = args['size'] or '3'
    local int = args['int'] or '0'
    local str = args['str'] or '0'
    local mov = args['mov'] or '0'
    local snk = args['snk'] or '0'
    local per = args['per'] or '0'

    local preAbilities = ''
    if (int == '0') then preAbilities = preAbilities .. "Normal Intelligence;; " end
    if (str == '0') then preAbilities = preAbilities .. "Normal Strength;; " end
    if (mov == '0') then preAbilities = preAbilities .. "Normal Movement;; " end
    if (snk == '0') then preAbilities = preAbilities .. "Normal Sneak;; " end
    if (per == '0') then preAbilities = preAbilities .. "Normal Perception;; " end

    local abilitiesString = preAbilities .. rawAbilities
    local opts = {
        name = name,
        ns = 'Creature',
        transparent = args.o or args.transparent
    }
    local tagOut, catOut = TagBuilder.build(tRaw, 'TagCreatures', 'traits', opts)

    -- === Parse and render main abilities with shared helpers ===
    local abilities = parseAbilitiesString(abilitiesString)
    local inner = buildAETransclusions(abilities)

    local categoryString = ''

    -- (stats/attributes rendering unchanged)
    -- ...

    local out = ""
    out = out .. makeBar(frame, "Stats", statContent, nul, nul, false)
    out = out .. makeBar(frame, "Attributes", attributeContent, nul, nul, false)
    out = out .. makeBar(frame, "Traits", (tagOut or ''), nul, nul, false)
    out = out .. makeBar(frame, "Looks", looks, nul, nul, false)
    if args['lifespan'] then
        local lifespanText = args['lifespan'] .. " years."
        categoryString = categoryString .. "[[Category:" .. args['lifespan'] .. " year lifespan creatures]]"
        if args['adult'] then
            lifespanText = lifespanText .. " Adult at age " .. args['adult'] .. "."
        end
        out = out .. makeBar(frame, "Lifespan", lifespanText, nul, nul, false)
    end

    out = out .. '<hr>'
    if args['d'] then out = out .. args['d'] .. '<hr>' end

    -- main abilities block
    out = out .. '<div class="expandable-table"><div>' .. frame:preprocess(inner) .. '</div></div>'

    -- === familiar abilities (args['f']) using the same parsing ===
    if args['f'] and mw.text.trim(args['f']) ~= '' then
        local fAbilities = parseAbilitiesString(args['f'])
        local fInner = buildAETransclusions(fAbilities)
        -- You can wrap in a bar or just mirror the main output style; here we label it:
        out = out .. makeBar(frame, "Familiar Abilities",
            frame:preprocess('<div class="expandable-table"><div>' .. fInner .. '</div></div>'),
            nul, nul, false)
    end

    out = out .. (catOut or '')

    local page = mw.title.getCurrentTitle().text
    local namespace = frame:preprocess('{{NAMESPACE}}')
    if ((namespace == "Creature") and (page == name)) then
        out = out .. categoryString
    end

    return frame:preprocess(out)
end

return p