Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Sandbox/Pavouk

From Wikipedia, the free encyclopedia
--
-- Implementuje šablonu  {{Historie počtu obyvatel}}
--
local p = {}
local lang = mw.getContentLanguage()
local Date -- lazy initialization

local function ifexist(page)
    if not page then return false end
    if mw.title.new(page).exists then return true end
    return false
end

local function isempty( s )
	return not s or s:match( '^%s*(.-)%s*$' ) == ''
end

local function splitnumandref( s )
	s = s:match( '^%s*(.-)%s*$' )
	local t1 = mw.text.unstrip(s)
        local t2 = s:match( '^([%d][%d,]*)' )
	if( t1 == t2 ) then
		local t3 = s:match( '^[%d][%d,]*(.-)$' )
		return t1, t3
	else
		return s, ''
	end
end

local function formatnumR(num)
	return tonumber(lang:parseFormattedNumber(num))
end

local function formatnum(num)
	return lang:parseFormattedNumber(num) and lang:formatNum(lang:parseFormattedNumber(num)) or num
end

-- this function creates an array with the {year, population, percent change}
local function getpoprow(year, popstr, pyear, ppopstr, linktype, percentages, current_year)
	local pop, popref = splitnumandref( popstr or '')
	local ppop, ppopref = splitnumandref( ppopstr or '')
	local percent = ''
	local yearnum = formatnumR(mw.ustring.gsub(year or '', '^%s*([%d][%d][%.%d]+).*$', '%1') or '')
	local pyearnum = formatnumR(mw.ustring.gsub(pyear or '', '^%s*([%d][%d][%.%d]+).*$', '%1') or '')
	local popnum = formatnumR(pop)
	local ppopnum = formatnumR(ppop)
	--if( linktype == 'US' or linktype == 'USA' ) then
	--	if( (yearnum or 0) >= 1790 and yearnum <= current_year and math.fmod(math.floor(yearnum), 10) == 0) then
	--		if( yearnum < current_year ) then
	--			year = '[[Sčítání lidu Spojených států amerických v roce '.. tostring(yearnum)..'|' .. year .. ']]'
  	--		elseif( ifexist('Sčítání lidu Spojených států amerických v roce '.. tostring(yearnum) ) ) then
	--			year = '[[Sčítání lidu Spojených států amerických v roce '.. tostring(yearnum)..'|' .. year .. ']]'
	--		end
	--	end
	--end
	
	if( linktype == 'ČR' or linktype == 'Česko' ) then
		if( yearnum  >= 1868 and yearnum <= current_year ) then
			if( yearnum <=1910 ) then
				year = '[[Sčítání lidu v Rakousko-Uhersku|' .. year .. ']]'
			elseif (yearnum==1921 or yearnum==1930) then
				year = '[[Sčítání lidu '.. tostring(yearnum).. 'v Československu|' .. year .. ']]'  -- Sčítání lidu 1921 v Československu   nebo Sčítání lidu 1930 v Československu
			elseif( yearnum ==1950 ) then
				year = '[[Národní sčítání 1950 v Československu|' .. year .. ']]'	
			elseif (yearnum>= 1950 and yearnum<= 1991 and ifexist('Sčítání lidu, domů a bytů '.. tostring(yearnum)..'v Československu' ) ) then
				 year = '[[Sčítání lidu, domů a bytů '.. tostring(yearnum).. 'v Československu|' .. year .. ']]' --např. Sčítání lidu, domů a bytů 1970 v Československu
			elseif (yearnum>= 2001 and ifexist('Sčítání lidu, domů a bytů '.. tostring(yearnum)..'v Česku' ) ) then
				 year = '[[Sčítání lidu, domů a bytů '.. tostring(yearnum).. 'v Česku|' .. year .. ']]' --např. Sčítání lidu, domů a bytů 2001 v Česku
			end
		end
	end
	
	if(percentages ~= 'off') then
		local pstr = '—&nbsp;&nbsp;&nbsp;&nbsp;'
		if(popnum ~= nil and ppopnum ~= nil and (ppopnum > 0)) then
			if(percentages == 'pagr') then
				pstr = mw.ustring.format('%.2f', 100*math.abs(math.pow(popnum/ppopnum,1/(yearnum-pyearnum)) - 1))
			elseif(percentages == 'monthly') then
				if Date == nil then Date = require('Module:Date')._Date end
				local date1 = Date(year)
				local date2 = Date(pyear)
				local diff = date1 - date2
				local months = (diff.age_days/(365.25/12))
				pstr = mw.ustring.format('%.2f', 100*math.abs(math.pow(popnum/ppopnum,1/months) - 1))
			else
				pstr = mw.ustring.format('%.1f', 100*math.abs(popnum/ppopnum - 1))
			end
			pstr = formatnum(pstr)
			if( popnum < ppopnum ) then
				pstr = '−' .. pstr .. ' %'
			else
				pstr = '+' .. pstr .. ' %'
			end
		elseif(popnum ~= nil and ppopnum ~= nil and (ppopnum == popnum)) then
			pstr = formatnum(mw.ustring.format('%.2f', 0)) .. ' %'
		end
		percent = pstr
	end
	-- strip the fractional part of the year, if there is one
	year = mw.ustring.gsub(year or '', '^%s*([%d][%d][%d]+)%.[%d]*', '%1')
	
	return {year, formatnum(pop) .. popref, percent }
end

-- this function creates an array with table header labels
local function getheadrow(percentages, popname, yearname, percentname)
	-- year cell	
	if(yearname == '') then
		yearname = 'Rok'
	end
	-- population cell
	if(popname == '') then
		popname = '<abbr title="Počet obyvatel" class="abbr-header">Obyv.</abbr>'
	end

	-- percentages cell
	if( percentages ~= 'off' and percentname == '') then
		if( percentages == 'pagr' ) then
			percentname = '<abbr title="Roční míra růstu" class="abbr-header">±% p.a.</abbr>'
		elseif( percentages == 'monthly' ) then
			percentname = '<abbr title="Měsíční míra růstu" class="abbr-header">±% p.m.</abbr>'
		else
			percentname = '<abbr title="Změna v procentech" class="abbr-header">± %</abbr>'
		end
	end
	return {yearname, popname, percentname}
end

-- this function builds the json for the population graph
local function graphjson(data, gwidth, gheight, gtype)
	local yearcount = #data
	local graphargs = {
		['width'] = gwidth,
		['height'] = gheight,
		['type'] = gtype or 'line',
		['yAxisTitle'] = 'Population',
		['yAxisMin'] = 0,
		['xAxisTitle'] = 'Year',
		['xAxisAngle'] = '-45',
		['yGrid'] = 'y',
		['yAxisFormat'] = ',d',
		['x'] = '',
		['y'] = ''
	}
	local firstpoint = true
	for offset = 1,yearcount do
		local x,y = data[offset][1], data[offset][2]
		-- delink if necessary
		if x:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then
			x = x:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]')
		end
		y = formatnumR(y)
		if x and y then
			graphargs['x'] = graphargs['x'] .. (firstpoint and '' or ', ') .. x
			graphargs['y'] = graphargs['y'] .. (firstpoint and '' or ', ') .. y
			firstpoint = false
		end
	end
	local Graph = require('Module:Graph')
	
	return Graph.chart({args = graphargs})
end

local function rendergraph(frame, data, gwidth, gheight, gthumb, gtype)
	local graph = frame:extensionTag{name = 'graph', content = graphjson(data, gwidth, gheight, gtype)}

	if(gthumb ~= '') then
		local graphdiv = mw.html.create('div')
			:addClass('thumb')
			:addClass(gthumb == 'right' and 'tright' or 'tleft')
			:css('clear', 'none')
		graphdiv
			:tag('div')
			:addClass('thumbinner')
			:wikitext(graph)
		return tostring(graphdiv)
	end
	
	return '<div class="center">' .. graph .. '</div>'
end

-- this function renders the population table in a vertical format
local function rendervertical(data, head, title, footnote, alignfn, class, style, width, shading, percol, cols, graphpos, graph)
	-- define a couple helper functions
	local function addrowcell(trow, tag, text, align, shading, style)
		cell = trow:tag(tag)
		cell
			:css('text-align', align)
			:css('padding', '1px')
			:wikitext(text)
			:css('border-bottom', shading ~= 'off' and '1px solid #bbbbbb' or nil)
			:cssText(style)
	end
	local function addheadcell(trow, text, align, width, pad)
		cell = trow:tag('th')
		cell
			:css('border-bottom', '1px solid var(--color-base, #000000)')
			:css('padding', pad and ('1px ' .. pad) or '1px')
			:css('text-align', align)
			:css('width', width)
			:wikitext(text)
	end

	local colspan = 3
	local yearcount = #data
	local argcount = 2*yearcount
	
	if( isempty(width) ) then
		width = '15em'
	end
	
	-- override the value of cols if percol has been specified
	if( percol > 0 ) then
		cols = math.floor( (yearcount - 1) / percol ) + 1
	end
	
	-- compute the number of rows per col
	local rowspercol = math.floor( (yearcount - 1) / cols ) + 1

	-- specify the colspan for the title and footer lines
	if( cols > 1 ) then
		colspan = cols
	else
		if (head[3] == '') then 
			colspan = 2
		else
			colspan = 3
		end
	end

	-- compute outer table width
	local twidth = width
	if( (cols > 1) and width:match('^%s*[%d]+[%w]+%s*$') ) then
		local widthnum = mw.ustring.gsub( width, '^%s*([%d]+)([%w]+)%s*$', '%1' )
		local widthunit = mw.ustring.gsub( width, '^%s*([%d]+)([%w]+)%s*$', '%2' )
		twidth = tostring(widthnum*cols) .. widthunit
	end
	
	-- create the outer table
	local root = mw.html.create('table')
	root
		:addClass(class)
		:css('width', twidth)
		:css('border-top-width', '0')
		:cssText(style['table'])
	-- add title
	local caption = root:tag('caption')
	caption
		:css('padding', '0.25em')
		:css('font-weight', 'bold')
		:attr('class', 'caption-purple')
		:wikitext(title)
		
	-- add the graph line (if top graph)
	if((graphpos == 'top' or graphpos == 't') and graph ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:attr('colspan', colspan)
			:css('border-bottom', '1px solid var(--color-base, #000000)')
			:wikitext(graph)
		graph = ''
	end
	
	-- loop over columns and rows within columns
	local offset = 1
	local t = root
	for c = 1,cols do
		-- add inner tables if we are rendering more than one column
		if( cols > 1) then
			if (c == 1) then
				row = root:tag('tr')
				row:attr('valign', 'top')
				cell = row:tag('td')
				cell
					:css('padding', '0 0.5em')
			else
				cell = row:tag('td')
				cell
					:css('padding', '0 0.5em')
					:css('border-left', 'solid 1px #aaa')
			end
			t = cell:tag('table')
			t
				:css('border-spacing', '0')
				:css('width', width)
		end
		-- start column headers
		local hrow = t:tag('tr')
		hrow:css('font-size', '95%')
		-- year header
		addheadcell(hrow, head[1], nil, head[3] ~= '' and '3em' or 'auto', nil, nil)
		-- population header
		addheadcell(hrow, head[2], 'right', nil, '2px')
		-- percentages header
		if( head[3] ~= '' ) then
			addheadcell(hrow, head[3], 'right', nil, nil)
		end
		-- end column headers
		-- start population rows
		for r = 1,rowspercol do
			-- generate the row if we have not exceeded the rowcount
			-- shade every fifth row, unless shading = off
			local s = 'off'
			if( math.fmod((c - 1)*rowspercol + r, 5) == 0 and r ~= rowspercol) then
				s = shading
			end
			if(offset <= yearcount) then
				-- start population row
				local prow = t:tag('tr')
				-- year cell
				addrowcell(prow, 'th', data[offset][1], 'center', s, style['year'])
				-- population cell
				addrowcell(prow, 'td', data[offset][2], 'right', s, style['pop'])
				-- percentage cell
				if( not isempty(head[3]) ) then
					addrowcell(prow, 'td', data[offset][3], 'right', s, style['pct'])
				end
				-- end population row
				offset = offset + 1
			end
		end
	end

	-- add the graph line (if bottom graph)
	if((graphpos == 'bottom' or graphpos == 'b') and graph ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:attr('colspan', colspan)
			:css('border-top', '1px solid var(--color-base, #000000)')
			:wikitext(graph)
		graph = ''
	end
	-- add the footnote line 	
	if( footnote ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:attr('colspan', colspan)
			:css('border-top', '1px solid var(--color-base, #000000)')
			:css('font-size', '85%')
			:css('text-align', alignfn)
			:wikitext(footnote)
	end
	
	return graph .. tostring(root)
end

-- this function renders the population table in a horizontal format
local function renderhorizontal(data, head, title, footnote, alignfn, class, style, width, shading, perrow, rows, graphpos, graph)
	local row
	local cell
	local yearcount = #data
	local argcount = 2*yearcount
	
	-- override the value of rows if perrow has been specified
	if( perrow > 0 ) then
		rows = math.floor( (yearcount - 1) / perrow ) + 1
	end
	
	-- compute the number of cols per row
	local colsperrow = math.floor( (yearcount - 1) / rows ) + 1

	-- create the outer table
	local root = mw.html.create('table')
	root
		:addClass(class)
		:css('font-size', '90%')
		:cssText(style['table'])
	-- create title row
	row = root:tag('tr')
	cell = row:tag('th')
	cell
		:css('padding', '0.25em')
		:attr('colspan', colsperrow + 1)
		:wikitext(title)

	-- add the graph line (if top graph)
	if((graphpos == 'top' or graphpos == 't') and graph ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:attr('colspan', colsperrow + 1)
			:css('border-bottom', '1px solid var(--color-base, #000000)')
			:wikitext(graph)
		graph = ''
	end

	-- loop over rows and columns within rows
	local offset = 1
	for r = 1,rows do
		local rowoffset = offset
		-- render the years
		row = root:tag('tr')
		cell = row:tag('th')
		cell:wikitext(head[1])
			:css('border-top', r > 1 and '2px solid #000' or nil)
		for c = 1,colsperrow do
			cell = row:tag('td')
			if(offset <= yearcount) then
				cell:wikitext(data[offset][1])
					:css('text-align', 'center')
					:css('border-top', r > 1 and '2px solid #000' or nil)
					:cssText(style['year'])
			else
				cell:css('border-width', r > 1 and '2px 0 0 0' or 0)
					:css('border-top', r > 1 and '2px solid #000' or nil)
			end
			offset = offset + 1
		end
		-- render the pop
		offset = rowoffset
		row = root:tag('tr')
		cell = row:tag('th')
		cell:wikitext(head[2])
		for c = 1,colsperrow do
			cell = row:tag('td')
			if(offset <= yearcount) then
				cell:wikitext(data[offset][2])
					:css('text-align', 'right')
					:css('padding-right', '2px')
					:cssText(style['pop'])
			else
				cell:css('border-width', 0)
			end
			offset = offset + 1
		end
		-- render the percentages
		if(head[3] ~= '') then
			offset = rowoffset
			row = root:tag('tr')
			cell = row:tag('th')
			cell:wikitext(head[3])
			for c = 1,colsperrow do
				cell = row:tag('td')
				if(offset <= yearcount) then
					cell:wikitext(data[offset][3])
						:css('text-align', 'right')
						:css('padding-right', '2px')
						:cssText(style['pct'])
				else
					cell:css('border-width', 0)
				end
				offset = offset + 1
			end
		end
	end
	
	-- add the graph line (if bottom graph)
	if((graphpos == 'bottom' or graphpos == 'b') and graph ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:attr('colspan', colsperrow + 1)
			:css('border-top', '1px solid var(--color-base, #000000)')
			:wikitext(graph)
		graph = ''
	end
	
	-- add the footnote line 	
	if( footnote ~= '') then
		row = root:tag('tr')
		cell = row:tag('td')
		cell
			:css('border-top', '2px solid var(--color-base, #000000)')
			:css('font-size', '85%')
			:css('text-align', alignfn)
			:attr('colspan', colsperrow + 1)
			:wikitext(footnote)
	end
	
	return graph .. tostring(root)
end

-- this is the main function
function p.poptable(frame)
	local data = {}
	local style = {}
	local args = frame.args[1] and frame.args or frame:getParent().args

	local title			= args['title']			or ''
	local align			= args['align']			or ''
	local clear			= args['clear']			or ''
	local direction		= args['direction']		or ''
	local percentages	= args['percentages']	or ''
	local state			= args['state']			or ''
	local linktype		= args['type']			or ''
	local shading		= args['shading']		or 'on'
	local width			= args['width']			or ''
	local subbox		= args['subbox']		or ''
	local popname		= args['pop_name']		or ''
	local yearname		= args['year_name']		or ''
	local percentname   = args['percent_name']  or ''
	local footnote		= args['footnote']		or ''
	local alignfn		= args['align-fn']		or ''
	local source		= args['source']		or ''
	local graphpos      = args['graph-pos']     or ''
	local graphwidth    = args['graph-width']   or ''
	local graphheight   = args['graph-height']  or ''
	local graphtype     = args['graph-type']    or 'line'
	local percol = tonumber(args['percol'])	or 0
	local cols	 = tonumber(args['cols'])	or 1
	local perrow = tonumber(args['perrow'])	or 0
	local rows	 = tonumber(args['rows'])	or 1
	style['year'] = args['year_style']
	style['pop']  = args['pop_style']
	style['pct']  = args['pct_style']

	-- setup classes and styling for outer table
	local class = direction == 'horizontal' and 'wikitable' or 'table-pale'
	if( state == 'collapsed' ) then
		class = class .. ' collapsible collapsed'
	end

	if( isempty(title) ) then
		title = 'Historie počtu obyvatel'
	end

	if( isempty(align) ) then
		align = direction ~= 'horizontal' and 'right' or 'center'
	end
	
	if( isempty(alignfn) ) then
		alignfn = 'left'
	end
	
	if( isempty(clear) ) then
		clear = align == 'center' and '' or align
	end
	
	local margin = '0.5em 0 1em 0.5em'
	if( align == 'left' ) then
		margin = '0.5em 1em 0.5em 0'
	elseif( align == 'none' ) then
		margin = '0.5em 1em 0.5em 0'
	elseif( align == 'center' ) then
		margin = '0.5em auto'
		align = ''
	end

	if( isempty(subbox) ) then
		style['table'] =
			'border-spacing: 0;' ..
			(align ~= '' and 'float:' .. align .. ';' or '') ..
			(clear ~= '' and 'clear:' .. clear .. ';' or '') ..
			'margin:' .. margin .. ';'
	else
		style['table'] =
			'margin:0;' ..
			'border-collapse:collapse;' ..
			'border:none;'
	end
	
	style['table'] = style['table'] .. (args['table_style'] or '')
		
	-- setup the footer text
	if( source ~= '' ) then
		source = 'Zdroj: ' .. source
		if( footnote ~= '' ) then
			footnote = footnote .. '<br/>'
		end
	end
	footnote = footnote .. source
	
	-- setup the data header cols/rows
	local head = getheadrow(percentages, popname, yearname, percentname)
	
	-- count the total number of population rows
	local argcount = 0
	local rowcount = 0
	for k, v in pairs( args ) do
		if ( (type( k ) == 'number') and (not isempty(args[k])) ) then
			if( k >= 1 and math.floor(k) == k and k > argcount) then
				argcount = k
			end
			if( math.fmod(k - 1, 2) == 0 ) then
				rowcount = rowcount + 1
			end
		end
	end

	-- here is where we build all the data for the table
	-- loop over columns and rows within columns
	local pyear = ''
	local ppop = ''
	local offset = 1
	local current_year = tonumber(os.date("%Y", os.time()))
	for r = 1,rowcount do
		-- skip blank rows
		while(isempty(args[offset]) and offset <= argcount) do
			offset = offset + 2
		end
		-- generate the row if we have not exceeded the rowcount
		if(offset <= argcount) then
			table.insert(data, getpoprow(args[offset], args[offset + 1] or '', pyear, ppop, 
				linktype, percentages, current_year) )
			pyear = args[offset]
			ppop = args[offset+1] or ''
			offset = offset + 2
		end
	end

	local graph = ''
	graphpos = graphpos:lower()
	-- now that we have the data for the table, render it in the requested format

	if (direction == 'horizontal') then
		if graphpos ~= '' then
			local gwidth = tonumber(graphwidth) or 200
			local gheight= tonumber(graphheight) or 170
			local gthumb = 
				(graphpos == 'r' or graphpos == 'right' and 'right') or
				(graphpos == 'l' or graphpos == 'left' and 'left') or ''
			graph = rendergraph(frame, data, gwidth, gheight, gthumb, graphtype)
		end
		return renderhorizontal(data, head, title, footnote, alignfn, class, style, width, shading, perrow, rows, graphpos, graph)
	else
		if graphpos ~= '' then
			local gwidth = tonumber(graphwidth) or (170 * cols)
			local gheight= tonumber(graphheight) or 170
			local gthumb = 
				(graphpos == 'r' or graphpos == 'right' and 'right') or
				(graphpos == 'l' or graphpos == 'left' and 'left') or ''
			graph = rendergraph(frame, data, gwidth, gheight, gthumb, graphtype)
		end
		return rendervertical(data, head, title, footnote, alignfn, class, style, width, shading, percol, cols, graphpos, graph)
	end

end

return p