---- This template implements --local p = local lang = mw.getContentLanguagelocal 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 falseend
local function isempty(s) return not s or s:match('^%s*(.-)%s*$')
local function splitnumandref(s) s = s:match('^%s*(.-)%s*$') local t1 = mw.text.unstrip(s) local t2 = s:match('^([%d][%d,]*)') if(t1
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 numend
-- this function creates an array with the 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
'USA') then if((yearnum or 0) >= 1790 and yearnum <= current_year and math.fmod(math.floor(yearnum), 10)
'pagr') then pstr = mw.ustring.format('%.2f', 100*math.abs(math.pow(popnum/ppopnum,1/(yearnum-pyearnum)) - 1)) elseif(percentages
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 if(popnum < ppopnum) then pstr = '−' .. pstr .. '%' else pstr = '+' .. pstr .. '%' end elseif(popnum ~= nil and ppopnum ~= nil and (ppopnum
-- this function creates an array with table header labelslocal function getheadrow(percentages, popname, yearname, percentname) -- year cell if(yearname
) then popname = 'Pop.' end
-- percentages cell if(percentages ~= 'off' and percentname
'pagr') then percentname = '±% p.a.' elseif(percentages
-- this function builds the json for the population graphlocal function graphjson(data, gwidth, gheight, gtype) local yearcount = #data local graphargs = 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.chartend
local function rendergraph(frame, data, gwidth, gheight, gthumb, gtype) local graph = frame:extensionTag
if(gthumb ~= ) then local graphdiv = mw.html.create('div') :addClass('thumb') :addClass(gthumb
' .. graph .. '
'end
-- this function renders the population table in a vertical formatlocal 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]
-- 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
'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
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
'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 formatlocal 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
'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
'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 functionfunction 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
'collapsed') then class = class .. ' collapsible collapsed' end
if(isempty(title)) then title = 'Historical population' 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
'left') 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 = 'Source: ' .. source if(footnote ~= ) then footnote = footnote .. '
' 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)
k and k > argcount) then argcount = k end if(math.fmod(k - 1, 2)
-- 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
'r' or graphpos
'l' or graphpos
'r' or graphpos
'l' or graphpos
end
return p