Module:ChapterList: Difference between revisions

From Candypedia
Table headers and other stuff loaded out of the other module
Tag: Reverted
Table headers and other stuff loaded out of the other module
Tag: Manual revert
Line 1: Line 1:
-- Module:ChapterList (enhanced)
-- Module:ChapterList
-- Builds a sortable chapter table with volume headers, "Not yet in print",
-- Reads Template:ChapterList, parses {{Chapter|...}}, and renders a sortable table.
-- and book-exclusive chapters. All metadata is pulled from Module:ChapterNavbox.
 
local p = {}
local p = {}


---------------------------------------------------------------------
-- Helper: format ISO date YYYY-MM-DD → M/D/YY
-- helpers
---------------------------------------------------------------------
local function formatDate(iso)
local function formatDate(iso)
     local y, m, d = iso:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$")
     local y, m, d = iso:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$")
     if not y then return iso or '' end
     if not y then return iso end
     return tonumber(m) .. "/" .. tonumber(d) .. "/" .. y:sub(3, 4)
     m = tonumber(m)
    d = tonumber(d)
    local yy = y:sub(3,4)
    return m .. "/" .. d .. "/" .. yy
end
end


-- numeric value of a chapter number (handles decimals)
function p.renderTable(frame)
local function numVal(n)
     -- Load raw wikitext of Template:ChapterList
     return tonumber(n) or 0
    local tpl = mw.title.new('Template:ChapterList')
end
    local raw = tpl and tpl:getContent() or ''
 
---------------------------------------------------------------------
-- pull data
---------------------------------------------------------------------
local nav = require('Module:ChapterNavbox') -- expects .volumes and .bookExclusiveChapters
local volumes = nav.volumes or {}
local bookExclusive = nav.bookExclusiveChapters or {}
 
-- read the raw wikitext list (Template:ChapterList)
local tplTitle = mw.title.new('Template:ChapterList')
local raw = tplTitle and tplTitle:getContent() or ''


-- parse {{Chapter|number=…|title=…|date=…}}
    -- Parse each {{Chapter|...}} line
local chapters = {}
    local chapters = {}
for _, line in ipairs(mw.text.split(raw, "\n", true)) do
    for line in raw:gmatch('[^\r\n]+') do
    local trimmed = mw.text.trim(line)
        local trimmed = mw.text.trim(line)
    if trimmed:find('^{{Chapter') then
        if trimmed:find('^{{Chapter') then
        local inner = trimmed:match('^{{Chapter%s*(.+)}}$')
            -- strip leading '{{Chapter' and trailing '}}'
        if inner then
            local inner = trimmed:match('^{{Chapter%s*(.+)}}$') or ''
            -- remove possible leading '|'
             if inner:sub(1,1) == '|' then inner = inner:sub(2) end
             if inner:sub(1,1) == '|' then inner = inner:sub(2) end
            -- split into key=value params
             local params = {}
             local params = {}
             for part in inner:gmatch('[^|]+') do
             for part in inner:gmatch('[^|]+') do
Line 44: Line 34:
             end
             end
             if params.number and params.title and params.date then
             if params.number and params.title and params.date then
                 table.insert(chapters, params)
                 table.insert(chapters, {
                    number = params.number,
                    title  = params.title,
                    date  = params.date
                })
             end
             end
         end
         end
     end
     end
end
-- sort chapters by numeric number
table.sort(chapters, function(a,b) return numVal(a.number) < numVal(b.number) end)
---------------------------------------------------------------------
-- build table
---------------------------------------------------------------------
local function addHeaderRow(out, text, colspan)
    table.insert(out, '|-')
    table.insert(out, '! colspan="' .. (colspan or 3) .. '" | ' .. text)
end
function p.renderTable(frame)
    local out = {
        '{| class="wikitable sortable"',
        '! #',
        '! Title',
        '! Published'
    }


     -- iterate volumes in declared order
     -- Build wikitable
     local used = {} -- track chapters already emitted
     local out = {}
     for _, vol in ipairs(volumes) do
     table.insert(out, '{| class="wikitable sortable"')
        -- header with optional style
    table.insert(out, '! #')
        local header = vol.name
    table.insert(out, '! Title')
        if vol.style and vol.style ~= '' then
    table.insert(out, '! Published')
            table.insert(out, '|-')
            table.insert(out, '! colspan="3" style="' .. vol.style .. '" | ' .. header)
        else
            addHeaderRow(out, header)
        end
 
        for _, ch in ipairs(chapters) do
            if not used[ch] then
                local n = numVal(ch.number)
                if n >= vol.start and n <= vol.end_ then
                    used[ch] = true
                    local isInter = tostring(ch.number):find('%.')
                    local dispNum = isInter and '' or ch.number
                    local dispTitle = isInter and ('Intermission: [[' .. ch.title .. ']]')
                                                  or ('[[' .. ch.title .. ']]')
                    table.insert(out, '|-')
                    table.insert(out, '| ' .. dispNum .. ' || ' .. dispTitle .. ' || ' .. formatDate(ch.date))
                end
            end
        end
    end


    -- Not yet in print header
    addHeaderRow(out, 'Not yet in print')
     for _, ch in ipairs(chapters) do
     for _, ch in ipairs(chapters) do
         if not used[ch] then
         local isInter = ch.number:find('%.')
            local isInter = tostring(ch.number):find('%.')
        local dispNum = isInter and '' or ch.number
            local dispNum = isInter and '' or ch.number
        local dispTitle = isInter
            local dispTitle = isInter and ('Intermission: [[' .. ch.title .. ']]')
            and ('Intermission: [[' .. ch.title .. ']]')
                                              or ('[[' .. ch.title .. ']]')
            or ('[[' .. ch.title .. ']]')
            table.insert(out, '|-')
        local dispDate = formatDate(ch.date)
            table.insert(out, '| ' .. dispNum .. ' || ' .. dispTitle .. ' || ' .. formatDate(ch.date))
         table.insert(out, '|-')
            used[ch] = true
        table.insert(out, '| ' .. dispNum .. ' || ' .. dispTitle .. ' || ' .. dispDate)
        end
    end
 
    -- Book-exclusive header
    if #bookExclusive > 0 then
         addHeaderRow(out, 'Book-exclusive')
        for _, be in ipairs(bookExclusive) do
            local link = be.link or be.title:gsub(' ', '_')
            table.insert(out, '|-')
            table.insert(out, '| || [[' .. link .. '|' .. be.title .. ']] || ')
        end
     end
     end



Revision as of 00:21, 24 April 2025

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

-- Module:ChapterList
-- Reads Template:ChapterList, parses {{Chapter|...}}, and renders a sortable table.
local p = {}

-- Helper: format ISO date YYYY-MM-DD → M/D/YY
local function formatDate(iso)
    local y, m, d = iso:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$")
    if not y then return iso end
    m = tonumber(m)
    d = tonumber(d)
    local yy = y:sub(3,4)
    return m .. "/" .. d .. "/" .. yy
end

function p.renderTable(frame)
    -- Load raw wikitext of Template:ChapterList
    local tpl = mw.title.new('Template:ChapterList')
    local raw = tpl and tpl:getContent() or ''

    -- Parse each {{Chapter|...}} line
    local chapters = {}
    for line in raw:gmatch('[^\r\n]+') do
        local trimmed = mw.text.trim(line)
        if trimmed:find('^{{Chapter') then
            -- strip leading '{{Chapter' and trailing '}}'
            local inner = trimmed:match('^{{Chapter%s*(.+)}}$') or ''
            -- remove possible leading '|'
            if inner:sub(1,1) == '|' then inner = inner:sub(2) end
            -- split into key=value params
            local params = {}
            for part in inner:gmatch('[^|]+') do
                local k, v = part:match('^(%w+)%s*=%s*(.+)$')
                if k and v then params[k] = v end
            end
            if params.number and params.title and params.date then
                table.insert(chapters, {
                    number = params.number,
                    title  = params.title,
                    date   = params.date
                })
            end
        end
    end

    -- Build wikitable
    local out = {}
    table.insert(out, '{| class="wikitable sortable"')
    table.insert(out, '! #')
    table.insert(out, '! Title')
    table.insert(out, '! Published')

    for _, ch in ipairs(chapters) do
        local isInter = ch.number:find('%.')
        local dispNum = isInter and '' or ch.number
        local dispTitle = isInter
            and ('Intermission: [[' .. ch.title .. ']]')
            or ('[[' .. ch.title .. ']]')
        local dispDate = formatDate(ch.date)
        table.insert(out, '|-')
        table.insert(out, '| ' .. dispNum .. ' || ' .. dispTitle .. ' || ' .. dispDate)
    end

    table.insert(out, '|}')
    return table.concat(out, '\n')
end

return p