<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ANavbox_timeline</id>
	<title>Module:Navbox timeline - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ANavbox_timeline"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Navbox_timeline&amp;action=history"/>
	<updated>2026-05-24T08:40:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Navbox_timeline&amp;diff=144104&amp;oldid=prev</id>
		<title>imported&gt;WOSlinker: use require(&#039;strict&#039;) instead of require(&#039;Module:No globals&#039;)</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Navbox_timeline&amp;diff=144104&amp;oldid=prev"/>
		<updated>2022-10-21T19:48:27Z</updated>

		<summary type="html">&lt;p&gt;use require(&amp;#039;strict&amp;#039;) instead of require(&amp;#039;Module:No globals&amp;#039;)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local yesno = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local navbox = require(&amp;#039;Module:Navbox&amp;#039;)._navbox&lt;br /&gt;
local getArgs = require(&amp;#039;Module:Arguments&amp;#039;).getArgs&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Add blank table cells&lt;br /&gt;
local function addBlank(args, row, prev, current)&lt;br /&gt;
	if row and prev &amp;lt; current then&lt;br /&gt;
		if yesno(args.decades) == false then&lt;br /&gt;
			row:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;timeline-blank&amp;#039;)&lt;br /&gt;
				:cssText(args.blankstyle)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;, current - prev)&lt;br /&gt;
		else&lt;br /&gt;
			-- Divide the cell up every decade if showing decades at the top&lt;br /&gt;
			local year = prev&lt;br /&gt;
			&lt;br /&gt;
			while year &amp;lt; current do&lt;br /&gt;
				local dur = math.min(10 - year % 10, current - year)&lt;br /&gt;
				&lt;br /&gt;
				row:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
					:addClass(&amp;#039;timeline-blank&amp;#039;)&lt;br /&gt;
					:cssText(args.blankstyle)&lt;br /&gt;
					:attr(&amp;#039;colspan&amp;#039;, dur)&lt;br /&gt;
				&lt;br /&gt;
				year = year + dur&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Get timeline data&lt;br /&gt;
local function timelineInfo(args)&lt;br /&gt;
	local rows = {&lt;br /&gt;
		[1] = {},&lt;br /&gt;
		minYear = math.huge,&lt;br /&gt;
		maxYear = -math.huge,&lt;br /&gt;
		hasLabels = false&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	for num, fullVal in ipairs(args) do&lt;br /&gt;
		local key, val = fullVal:match(&amp;#039;^([a-z]+): *(.*)$&amp;#039;)&lt;br /&gt;
		local cellIndex = #rows[#rows]&lt;br /&gt;
		&lt;br /&gt;
		-- Row data key value pairs&lt;br /&gt;
		if cellIndex == 0 and key then&lt;br /&gt;
			rows[#rows][key] = val&lt;br /&gt;
			&lt;br /&gt;
			-- Record that there are labels&lt;br /&gt;
			if key == &amp;#039;label&amp;#039; then&lt;br /&gt;
				rows.hasLabels = true&lt;br /&gt;
			end&lt;br /&gt;
		-- Data cell key value pairs&lt;br /&gt;
		elseif key then&lt;br /&gt;
			-- Data cell key value pairs&lt;br /&gt;
			rows[#rows][cellIndex][key] = val&lt;br /&gt;
		-- New row&lt;br /&gt;
		elseif fullVal == &amp;#039;&amp;#039; then&lt;br /&gt;
			if next(rows[#rows]) then&lt;br /&gt;
				table.insert(rows, {})&lt;br /&gt;
			end&lt;br /&gt;
		-- Add date to cell with item already and no date&lt;br /&gt;
		elseif cellIndex &amp;gt; 0&lt;br /&gt;
			and rows[#rows][cellIndex].item&lt;br /&gt;
			and not rows[#rows][cellIndex].startYear&lt;br /&gt;
		then&lt;br /&gt;
			local dates = mw.text.split(fullVal, &amp;#039;-&amp;#039;, true)&lt;br /&gt;
			local startYear = tonumber(dates[1])&lt;br /&gt;
			local endYear = tonumber(dates[2]) or tonumber(os.date(&amp;#039;%Y&amp;#039;)) + 1&lt;br /&gt;
			&lt;br /&gt;
			if startYear == nil then&lt;br /&gt;
				error(&amp;#039;Argument &amp;#039; .. num .. &amp;#039; is an invalid time range&amp;#039;, 0)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			if endYear &amp;lt; startYear then&lt;br /&gt;
				error(&amp;#039;Argument &amp;#039; .. num .. &amp;#039;\&amp;#039;s end year is less than the start year&amp;#039;, 0)&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			rows[#rows][cellIndex].startYear = startYear&lt;br /&gt;
			rows[#rows][cellIndex].endYear = endYear&lt;br /&gt;
&lt;br /&gt;
			if startYear &amp;lt; rows.minYear then&lt;br /&gt;
				rows.minYear = startYear&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if endYear &amp;gt; rows.maxYear then&lt;br /&gt;
				rows.maxYear = endYear&lt;br /&gt;
			end&lt;br /&gt;
		-- New item&lt;br /&gt;
		else&lt;br /&gt;
			table.insert(rows[#rows], { item = fullVal })&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Add overrides from arguments&lt;br /&gt;
	if args.startoffset then&lt;br /&gt;
		rows.minYear = rows.minYear - tonumber(args.startoffset)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.startyear and tonumber(args.startyear) &amp;lt; rows.minYear then&lt;br /&gt;
		rows.minYear = tonumber(args.startyear)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.endoffset then&lt;br /&gt;
		rows.maxYear = rows.maxYear + tonumber(args.endoffset)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if args.endyear and tonumber(args.endyear) &amp;gt; rows.maxYear then&lt;br /&gt;
		rows.maxYear = tonumber(args.endyear)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return rows&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Render the date rows&lt;br /&gt;
local function renderDates(args, tbl, rows, invert)&lt;br /&gt;
	local showDecades = yesno(args.decades)&lt;br /&gt;
	local yearRow = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;timeline-row&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	-- Create label&lt;br /&gt;
	if args.label or rows.hasLabels then&lt;br /&gt;
		local labelCell = mw.html.create(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;navbox-group timeline-label&amp;#039;)&lt;br /&gt;
			:cssText(args.labelstyle)&lt;br /&gt;
			:attr(&amp;#039;rowspan&amp;#039;, showDecades ~= false and &amp;#039;2&amp;#039; or &amp;#039;1&amp;#039;)&lt;br /&gt;
			:wikitext(args.label or &amp;#039;&amp;#039;)&lt;br /&gt;
			&lt;br /&gt;
		yearRow:node(labelCell)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Create decade row&lt;br /&gt;
	if showDecades ~= false then&lt;br /&gt;
		local decadeRow = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;timeline-row&amp;#039;)&lt;br /&gt;
		local year = rows.minYear&lt;br /&gt;
		&lt;br /&gt;
		-- Move decade row &lt;br /&gt;
		if not invert then&lt;br /&gt;
			decadeRow, yearRow = yearRow, decadeRow&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		while year &amp;lt; rows.maxYear do&lt;br /&gt;
			local dur = math.min(10 - year % 10, rows.maxYear - year)&lt;br /&gt;
			&lt;br /&gt;
			decadeRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;timeline-decade&amp;#039;)&lt;br /&gt;
				:cssText(args.datestyle)&lt;br /&gt;
				:cssText(args.decadestyle)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;, dur)&lt;br /&gt;
				:wikitext(math.floor(year / 10) .. &amp;#039;0s&amp;#039;)&lt;br /&gt;
			&lt;br /&gt;
			year = year + dur&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Populate year row element&lt;br /&gt;
	local width = 100 / (rows.maxYear - rows.minYear)&lt;br /&gt;
	&lt;br /&gt;
	for i = rows.minYear, rows.maxYear - 1 do&lt;br /&gt;
		yearRow:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
			:attr(&amp;#039;scope&amp;#039;, &amp;#039;col&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;timeline-year&amp;#039;)&lt;br /&gt;
			:cssText(args.datestyle)&lt;br /&gt;
			:cssText(args.yearstyle)&lt;br /&gt;
			:cssText(&amp;#039;width:&amp;#039; .. width .. &amp;#039;%&amp;#039;)&lt;br /&gt;
			:wikitext(showDecades == false and i or i % 10)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Render the timeline itself&lt;br /&gt;
local function renderTimeline(args, tbl, rows)&lt;br /&gt;
	local rowElement = nil&lt;br /&gt;
	local rowSuffix = nil&lt;br /&gt;
	local prev = rows.minYear&lt;br /&gt;
	local prevItem = nil&lt;br /&gt;
	local prevLabel = nil&lt;br /&gt;
	local labelSpan = 0&lt;br /&gt;
	&lt;br /&gt;
	for rowNum, row in ipairs(rows) do&lt;br /&gt;
		local rowElement = tbl:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;timeline-row&amp;#039;)&lt;br /&gt;
		&lt;br /&gt;
		if labelSpan &amp;lt;= 0 and (rows.hasLabels or args.label) then&lt;br /&gt;
			labelSpan = tonumber(row.span) or 1&lt;br /&gt;
			&lt;br /&gt;
			prevLabel = rowElement:tag(&amp;#039;th&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;scope&amp;#039;, &amp;#039;row&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;rowspan&amp;#039;, labelSpan)&lt;br /&gt;
				:addClass(&amp;#039;navbox-group timeline-label&amp;#039;)&lt;br /&gt;
				:cssText(args.labelstyle)&lt;br /&gt;
				:cssText(row.labelstyle)&lt;br /&gt;
				:wikitext(row.label)&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		labelSpan = labelSpan - 1&lt;br /&gt;
		&lt;br /&gt;
		local prevEndYear = rows.minYear&lt;br /&gt;
		local prevItem = nil&lt;br /&gt;
		&lt;br /&gt;
		for cellNum, cell in ipairs(row) do&lt;br /&gt;
			-- Shrink previous item so new item can start at the start year&lt;br /&gt;
			if prevItem and prev &amp;gt; prevEndYear then&lt;br /&gt;
				prevItem:attr(&amp;#039;colspan&amp;#039;, prevItem:getAttr(&amp;#039;colspan&amp;#039;) - prev + prevEndYear);&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if cell.startYear == nil then&lt;br /&gt;
				error(&amp;#039;Missing timerange for row &amp;#039; .. rowNum .. &amp;#039; cell &amp;#039; .. cellNum, 0)&lt;br /&gt;
			end&lt;br /&gt;
			&lt;br /&gt;
			-- Add blanks before the cell&lt;br /&gt;
			addBlank(args, rowElement, prevEndYear, cell.startYear)&lt;br /&gt;
			&lt;br /&gt;
			prevItem = rowElement:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;timeline-item&amp;#039;)&lt;br /&gt;
				:cssText(args.itemstyle)&lt;br /&gt;
				:cssText(cell.style or &amp;#039;&amp;#039;)&lt;br /&gt;
				:attr(&amp;#039;colspan&amp;#039;, cell.endYear - cell.startYear)&lt;br /&gt;
				:wikitext(cell.item)&lt;br /&gt;
&lt;br /&gt;
			prevEndYear = cell.endYear&lt;br /&gt;
		end&lt;br /&gt;
		&lt;br /&gt;
		-- Add blanks to the end of the row&lt;br /&gt;
		addBlank(args, rowElement, prevEndYear, rows.maxYear)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Remove any extra rowspan from the label&lt;br /&gt;
	if prevLabel and labelSpan &amp;gt; 0 then&lt;br /&gt;
		prevLabel:attr(&amp;#039;rowspan&amp;#039;, prevLabel:getAttr(&amp;#039;rowspan&amp;#039;) - labelSpan);&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	local args = getArgs(frame, {&lt;br /&gt;
		removeBlanks = false,&lt;br /&gt;
		wrappers = &amp;#039;Template:Navbox timeline&amp;#039;&lt;br /&gt;
	})&lt;br /&gt;
	local targs = {&lt;br /&gt;
		listpadding = &amp;#039;0&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
	-- Arguments to passthrough to navbox&lt;br /&gt;
	local passthrough = {&lt;br /&gt;
		&amp;#039;name&amp;#039;, &amp;#039;title&amp;#039;, &amp;#039;above&amp;#039;, &amp;#039;below&amp;#039;, &amp;#039;state&amp;#039;, &amp;#039;navbar&amp;#039;, &amp;#039;border&amp;#039;, &amp;#039;image&amp;#039;,&lt;br /&gt;
		&amp;#039;imageleft&amp;#039;, &amp;#039;style&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;style&amp;#039;, &amp;#039;bodystyle&amp;#039;, &amp;#039;basestyle&amp;#039;,&lt;br /&gt;
		&amp;#039;titlestyle&amp;#039;, &amp;#039;abovestyle&amp;#039;, &amp;#039;belowstyle&amp;#039;, &amp;#039;imagestyle&amp;#039;,&lt;br /&gt;
		&amp;#039;imageleftstyle&amp;#039;, &amp;#039;titleclass&amp;#039;, &amp;#039;aboveclass&amp;#039;, &amp;#039;bodyclass&amp;#039;, &amp;#039;belowclass&amp;#039;,&lt;br /&gt;
		&amp;#039;imageclass&amp;#039;&lt;br /&gt;
	}&lt;br /&gt;
	local rows = timelineInfo(args)&lt;br /&gt;
	local wrapper = mw.html.create(&amp;#039;table&amp;#039;)&lt;br /&gt;
		:addClass(&amp;#039;timeline-wrapper&amp;#039;)&lt;br /&gt;
	local tbl = wrapper:tag(&amp;#039;tr&amp;#039;)&lt;br /&gt;
		:tag(&amp;#039;td&amp;#039;)&lt;br /&gt;
			:addClass(&amp;#039;timeline-wrapper-cell&amp;#039;)&lt;br /&gt;
			:tag(&amp;#039;table&amp;#039;)&lt;br /&gt;
				:addClass(&amp;#039;timeline-table&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	renderDates(args, tbl, rows)&lt;br /&gt;
	renderTimeline(args, tbl, rows)&lt;br /&gt;
	&lt;br /&gt;
	if yesno(args.footer) then&lt;br /&gt;
		renderDates(args, tbl, rows, true)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	for _, name in ipairs(passthrough) do &lt;br /&gt;
		targs[name] = args[name]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	targs.templatestyles = &amp;#039;Module:Navbox timeline/styles.css&amp;#039;&lt;br /&gt;
	targs.list1 = tostring(wrapper)&lt;br /&gt;
	&lt;br /&gt;
	return navbox(targs)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>imported&gt;WOSlinker</name></author>
	</entry>
</feed>