Scheduled Maintenance
The wiki will be going down for routine maintenance on Friday, October 4th, 2024, at approximately 3:30 PM Central Time (15:30) or 1:30 PM Pacific Time. The site may be inaccessible during this time and the database will be locked from editing. We expect the maintenance to take about thirty minutes. We strongly encourage joining our Discord for updates.
Module:Timeline: Difference between revisions
Jump to navigation
Jump to search
en>BrandonXLF (Added comments and added rowspan for labels) |
m (1 revision imported) |
Latest revision as of 19:55, 26 August 2021
This module depends on the following other modules: |
This module implements the {{Timeline}} template. Please see the template page for usage instructions.
require('Module:No globals')
local yesno = require('Module:Yesno')
local navbox = require('Module:Navbox')._navbox
local getArgs = require('Module:Arguments').getArgs
local p = {}
-- Add a blank table cell
local function addBlank(args, row, prev, current)
if row and prev < current then
if yesno(args.decades) == false then
row:tag('td')
:addClass('timeline-blank')
:cssText(args.blankstyle)
:attr('colspan', current - prev)
-- Divide the cell up every decade if showing decades at the top
else
local year = prev
while year < current do
local dur = math.min(10 - year % 10, current - year)
row:tag('td')
:addClass('timeline-blank')
:cssText(args.blankstyle)
:attr('colspan', dur)
year = year + dur
end
end
end
end
-- Get timeline entries, start years, and end years
local function timelineInfo(args)
local info = {
startYear = math.huge,
startYears = {},
endYear = 0,
endYears = {},
entries = {}
}
for k, _ in pairs(args) do
if type(k) == 'string' then
local num = k:match('^%a+(%d+)$')
if num then
table.insert(info.entries, tonumber(num))
end
end
end
table.sort(info.entries)
for i, num in ipairs(info.entries) do
if args['item' .. i] then
if not args['date' .. i] then
error('item' .. i .. ' requires a corresponding ' .. 'date' .. i, 0)
end
local dates = mw.text.split(args['date' .. i], '-', true)
local startYear = tonumber(dates[1])
local endYear = tonumber(dates[2]) or tonumber(os.date('%Y')) + 1
if not startYear then
error('date' .. i .. ' contains an invalid timerange', 0)
end
info.startYear = math.min(info.startYear, startYear)
info.endYear = math.max(info.endYear, endYear)
info.startYears[i] = startYear
info.endYears[i] = endYear
end
end
if args.startoffset then
info.startYear = info.startYear - tonumber(args.startoffset)
end
if args.startyear then
info.startYear = math.min(info.startYear, tonumber(args.startyear))
end
if args.endoffset then
info.endYear = info.endYear + tonumber(args.endoffset)
end
if args.endyear then
info.endYear = math.max(info.endYear, tonumber(args.endyear))
end
return info
end
-- Render the date rows
local function renderDates(args, tbl, info)
local showDecades = yesno(args.decades)
local labelRow = nil
if args.label then
labelRow = mw.html.create('th')
:attr('scope', 'col')
:addClass('navbox-group timeline-label')
:cssText(args.labelstyle)
:attr('rowspan', showDecades ~= false and '2' or '1')
:wikitext(args.label or '')
end
-- Render the decades row
if showDecades ~= false then
local decadeRow = tbl:tag('tr')
local year = info.startYear
decadeRow:node(labelRow)
while year < info.endYear do
local dur = math.min(10 - year % 10, info.endYear - year)
decadeRow:tag('th')
:attr('scope', 'col')
:addClass('timeline-decade')
:cssText(args.datestyle)
:cssText(args.decadestyle)
:attr('colspan', dur)
:wikitext(math.floor(year / 10) .. '0s')
year = year + dur
end
end
-- Render the years row
local yearRow = tbl:tag('tr')
local width = 100 / (info.endYear - info.startYear)
if showDecades == false then
yearRow:node(labelRow)
end
for i = info.startYear, info.endYear - 1 do
yearRow:tag('th')
:attr('scope', 'col')
:addClass('timeline-year')
:cssText(args.datestyle)
:cssText(args.yearstyle)
:cssText('width:' .. width .. '%')
:wikitext(showDecades == false and i or i % 10)
end
end
-- Render the timeline itself
local function renderTimeline(args, tbl, info)
local row = nil
local prev = info.startYear
local prevItem = nil
local prevLabel = nil
local labelSpan = 0
for i, num in ipairs(info.entries) do
if args['row' .. i] or row == nil then
addBlank(args, row, prev, info.endYear)
row = tbl:tag('tr')
prev = info.startYear
if labelSpan <= 0 and args.label then
labelSpan = tonumber(args['span' .. i]) or 1
prevLabel = row:tag('th')
:attr('scope', 'row')
:attr('rowspan', labelSpan)
:addClass('navbox-group timeline-label')
:cssText(args.labelstyle)
:cssText(args['labelstyle' .. i] or '')
:wikitext(args['row' .. i])
end
labelSpan = labelSpan - 1
end
if args['item' .. i] then
local content = args['item' .. i]
local startYear = info.startYears[i]
local endYear = info.endYears[i]
addBlank(args, row, prev, startYear)
-- Shrink previous item so new item can start at the start year
if prevItem and prev > startYear then
prevItem:attr('colspan', prevItem:getAttr('colspan') - prev + startYear);
end
prevItem = row:tag('td')
:addClass('timeline-item')
:cssText(args.itemstyle)
:cssText(args['style' .. i] or '')
:attr('colspan', endYear - startYear)
:wikitext(content)
prev = endYear
end
end
-- Remove any extra rowspan from the label
if prevLabel and labelSpan > 0 then
prevLabel:attr('rowspan', prevLabel:getAttr('rowspan') - labelSpan);
end
addBlank(args, row, prev, info.endYear)
end
function p.main(frame)
local args = getArgs(frame, {
removeBlanks = false,
wrappers = 'Template:Timeline'
})
local targs = {
listpadding = '0'
}
-- Arguments to passthrough to navbox
local passthrough = {
'name', 'title', 'above', 'below', 'state', 'navbar', 'border', 1,
'image', 'imageleft', 'style', 'bodystyle', 'style', 'bodystyle',
'basestyle', 'titlestyle', 'abovestyle', 'belowstyle', 'imagestyle',
'imageleftstyle', 'titleclass', 'aboveclass', 'bodyclass',
'belowclass', 'imageclass'
}
local info = timelineInfo(args)
local tbl = mw.html.create('table'):addClass('timeline-table')
renderDates(args, tbl, info)
renderTimeline(args, tbl, info)
if yesno(args.footer) then
renderDates(args, tbl, info)
end
for _, name in ipairs(passthrough) do
targs[name] = args[name]
end
targs.list1 = frame:extensionTag{
name = 'templatestyles',
args = {
src = 'Template:Timeline/style.css'
}
} .. tostring(tbl)
return navbox(targs)
end
return p