Module:ChapterList: Difference between revisions
Table headers and other stuff loaded out of the other module Tag: Manual revert |
Major improvements |
||
| Line 1: | Line 1: | ||
-- Module:ChapterList | -- Module:ChapterList (enhanced) | ||
-- | -- Builds a sortable chapter table with volume headers, "Not yet in print", | ||
-- and book‑exclusive chapters. All metadata is pulled from Module:ChapterNavbox. | |||
local p = {} | local p = {} | ||
-- | --------------------------------------------------------------------- | ||
-- 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 end | if not y then return iso or '' end | ||
return tonumber(m) .. "/" .. tonumber(d) .. "/" .. y:sub(3, 4) | |||
end | end | ||
function | -- numeric value of a chapter number (handles decimals) | ||
-- | local function numVal(n) | ||
return tonumber(n) or 0 | |||
end | |||
--------------------------------------------------------------------- | |||
-- 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=…}} | |||
local chapters = {} | |||
for _, line in ipairs(mw.text.split(raw, "\n", true)) do | |||
local trimmed = mw.text.trim(line) | |||
if trimmed:find('^{{Chapter') then | |||
local inner = trimmed:match('^{{Chapter%s*(.+)}}$') | |||
if inner then | |||
if inner:sub(1,1) == '|' then inner = inner:sub(2) end | if inner:sub(1,1) == '|' then inner = inner:sub(2) end | ||
local params = {} | local params = {} | ||
for part in inner:gmatch('[^|]+') do | for part in inner:gmatch('[^|]+') do | ||
| Line 34: | Line 44: | ||
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, | table.insert(chapters, params) | ||
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 | ||
local | local used = {} -- track chapters already emitted | ||
table.insert(out, ' | for _, vol in ipairs(volumes) do | ||
-- header with optional style | |||
local header = vol.name | |||
if vol.style and vol.style ~= '' then | |||
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 | ||
local isInter = ch.number:find('%.') | if not used[ch] then | ||
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, '|-') | table.insert(out, '| ' .. dispNum .. ' || ' .. dispTitle .. ' || ' .. formatDate(ch.date)) | ||
used[ch] = true | |||
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 | ||
Latest revision as of 00:21, 24 April 2025
Documentation for this module may be created at Module:ChapterList/doc
-- Module:ChapterList (enhanced)
-- Builds a sortable chapter table with volume headers, "Not yet in print",
-- and book‑exclusive chapters. All metadata is pulled from Module:ChapterNavbox.
local p = {}
---------------------------------------------------------------------
-- helpers
---------------------------------------------------------------------
local function formatDate(iso)
local y, m, d = iso:match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$")
if not y then return iso or '' end
return tonumber(m) .. "/" .. tonumber(d) .. "/" .. y:sub(3, 4)
end
-- numeric value of a chapter number (handles decimals)
local function numVal(n)
return tonumber(n) or 0
end
---------------------------------------------------------------------
-- 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=…}}
local chapters = {}
for _, line in ipairs(mw.text.split(raw, "\n", true)) do
local trimmed = mw.text.trim(line)
if trimmed:find('^{{Chapter') then
local inner = trimmed:match('^{{Chapter%s*(.+)}}$')
if inner then
if inner:sub(1,1) == '|' then inner = inner:sub(2) end
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, params)
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
local used = {} -- track chapters already emitted
for _, vol in ipairs(volumes) do
-- header with optional style
local header = vol.name
if vol.style and vol.style ~= '' then
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
if not used[ch] then
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))
used[ch] = true
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
table.insert(out, '|}')
return table.concat(out, '\n')
end
return p