Module:Timeline
Documentation for this module may be created at Module:Timeline/doc
Documentation for this module may be created at Module:Timeline/doc
require('strict')
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')
:addClass('timeline-row')
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')
:addClass('timeline-row')
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')
:addClass('timeline-row')
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 wrapper = mw.html.create('table')
:addClass('timeline-wrapper')
local tbl = wrapper:tag('tr')
:tag('td')
:addClass('timeline-wrapper-cell')
:tag('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 = 'Module:Timeline/styles.css'
}
} .. tostring(wrapper)
return navbox(targs)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.