|
|
Zeile 1: |
Zeile 1: |
− | -- this module implements [[Template:Overlay]]
| |
− | local p = {}
| |
| | | |
− | local mArguments = require('Module:Arguments')
| |
− |
| |
− | -- used to cache the calculated font color to avoid repeat calculations
| |
− | local previous_backgroundcolor = ''
| |
− | local fontcolor = ''
| |
− |
| |
− | local function buildicon(n, form, lk, c, t)
| |
− | local res
| |
− | if form == 'text' then
| |
− | return tostring(
| |
− | mw.html.create('span')
| |
− | :css('font-weight', 'bold')
| |
− | :css('color', c)
| |
− | :wikitext(n)
| |
− | )
| |
− | elseif form == 'color' or form == 'colour' then
| |
− | return tostring(
| |
− | mw.html.create('span')
| |
− | :css('background-color', c)
| |
− | :wikitext('  ')
| |
− | )
| |
− | else
| |
− | -- check if the color is difference from the previous color
| |
− | if c ~= previous_backgroundcolor then
| |
− | -- color changed, so look up the best font color
| |
− | local greatercontrast = require('Module:Color contrast')._greatercontrast
| |
− | fontcolor = greatercontrast{c, 'white', 'black', bias = 1.3}
| |
− | -- update the previous value for the next check
| |
− | previous_backgroundcolor = c
| |
− | end
| |
− | -- build the inner span for the icon
| |
− | local span = mw.html.create('span')
| |
− | :css('color', fontcolor)
| |
− | :css('font-size', '88%')
| |
− | :css('font-weight', 'bold')
| |
− | :attr('title', t)
| |
− | :wikitext(n)
| |
− | -- build the outer div
| |
− | local div = mw.html.create('div')
| |
− | :css('display', 'inline-block')
| |
− | :css('width', 'auto')
| |
− | :css('height', 'auto')
| |
− | :css('text-align', 'center')
| |
− | :css('padding', ((tonumber(n) or 0) < 10) and '0px 4px' or '0px 2px')
| |
− | :css('vertical-align', 'middle')
| |
− | :css('border-radius', '3px')
| |
− | :css('background-color', c)
| |
− |
| |
− | -- link the inner span if requested and insert in the div
| |
− | if lk ~= '' then
| |
− | div:wikitext('[[:' .. lk .. '|' .. tostring(span) .. ']]')
| |
− | else
| |
− | div:wikitext(tostring(span))
| |
− | end
| |
− | -- convert to a string
| |
− | return tostring(div)
| |
− | end
| |
− | end
| |
− |
| |
− | local function buildlegend(data, cols, border, caption)
| |
− | -- create the outer table to hold the columns
| |
− | local root = mw.html.create('table')
| |
− | :css('width', '100%')
| |
− | :css('border', (border ~= 'no') and '1px #ccc solid' or '')
| |
− | -- create the outer row which will contain the columns
| |
− | local outerrow = root:tag('tr')
| |
− | local percol = math.ceil((#data) / cols)
| |
− | local k = 0
| |
− | for j=1,cols do
| |
− | -- create the outer cell to hold this column
| |
− | local colcell = outerrow:tag('td')
| |
− | :css('width', (math.floor(10/cols)/10) .. '%')
| |
− | :css('vertical-align', 'top')
| |
− | -- create the inner table to hold the entries in the column
| |
− | local coltable = colcell:tag('table')
| |
− | :css('width', '100%')
| |
− | :css('font-size', '85%')
| |
− | :css('line-height', '95%')
| |
− | -- add the entries to the column
| |
− | for l = 1,percol do
| |
− | k = k + 1
| |
− | if k <= #data then
| |
− | local rdata = data[k]
| |
− | local tr = coltable:tag('tr'):css('vertical-align','top')
| |
− | tr:tag('td')
| |
− | :css('width', '12px')
| |
− | :css('text-align', 'right')
| |
− | :css('padding-bottom', '2px')
| |
− | :wikitext(rdata[1] or '')
| |
− | tr:tag('td')
| |
− | :css('padding-bottom', '2px')
| |
− | :wikitext(rdata[2] or '')
| |
− | end
| |
− | end
| |
− | end
| |
− | return caption .. tostring(root)
| |
− | end
| |
− |
| |
− | local function buildlegenditem(im, lk, t)
| |
− | local res = {im, ''}
| |
− | if t ~= '' then
| |
− | if lk ~= '' then
| |
− | res[2] = '[[:' .. lk .. '|' .. t .. ']]'
| |
− | else
| |
− | res[2] = t
| |
− | end
| |
− | else
| |
− | res[2] = '[[:' .. lk .. '|' .. lk .. ']]'
| |
− | end
| |
− | return res
| |
− | end
| |
− |
| |
− | function p.icon(frame)
| |
− | local args = mArguments.getArgs(frame)
| |
− | return tostring(
| |
− | mw.html.create('div')
| |
− | :css('display', 'inline-block')
| |
− | :css('line-height', '95%')
| |
− | :wikitext(buildicon(args['1'] or '',
| |
− | args['form'] or 'icon',
| |
− | args['link'] or '',
| |
− | args['2'] or 'red',
| |
− | args['tip'] or ''))
| |
− | )
| |
− | end
| |
− |
| |
− | function p.main(frame)
| |
− | local args = mArguments.getArgs(frame)
| |
− |
| |
− | local image = args['image'] or ''
| |
− | local width = tonumber(args['width'] or '500') or 500
| |
− | local height = tonumber(args['height'] or '500') or 500
| |
− | local columns = tonumber(args['columns'] or '3') or 3
| |
− | local grid = ((args['grid'] or ''):lower() == 'yes') and 'yes' or 'no'
| |
− | local legendbox = ((args['legendbox'] or ''):lower() == 'no') and 'no' or 'yes'
| |
− | local overlay = (image == '') and 'no' or ( ((args['overlay'] or ''):lower() == 'no') and 'no' or 'yes' )
| |
− | local float = args['float'] or 'center'
| |
− | local border = ((args['border'] or ''):lower() == 'no') and 'no' or 'yes'
| |
− | local padding = args['padding'] or ''
| |
− |
| |
− | -- create the root table
| |
− | local root = mw.html.create('table')
| |
− | if float == 'center' or float == 'centre' then
| |
− | root:css('margin-left', 'auto')
| |
− | :css('margin-right', 'auto')
| |
− | elseif float == 'right' then
| |
− | root:css('float', 'right')
| |
− | :css('clear', 'right')
| |
− | :css('margin-left', '1em')
| |
− | elseif float == 'left' then
| |
− | root:css('float', 'left')
| |
− | :css('clear', 'left')
| |
− | :css('margin-right', '1em')
| |
− | else
| |
− | root:css('float', float)
| |
− | end
| |
− | if border == 'yes' then
| |
− | root:css('border', '1px #ccc solid')
| |
− | end
| |
− |
| |
− | -- create a list of all the overlay numbers
| |
− | local itemnums = {}
| |
− | for k, v in pairs( args ) do
| |
− | local i = tonumber(tostring(k):match( '^%s*overlay([%d]+)%s*$' ) or '-1')
| |
− | if i > -1 then
| |
− | table.insert(itemnums, i)
| |
− | else
| |
− | i = tonumber(tostring(k):match( '^%s*overlay([%d]+)tip%s*$' ) or '-1')
| |
− | if i > -1 then
| |
− | table.insert(itemnums, i)
| |
− | end
| |
− | end
| |
− | end
| |
− | -- sort to process in order
| |
− | table.sort( itemnums )
| |
− |
| |
− | -- remove duplicates
| |
− | for k = 2,#itemnums do
| |
− | if itemnums[k] == itemnums[k-1] then
| |
− | table.remove(itemnums, k)
| |
− | end
| |
− | end
| |
− |
| |
− | -- build the overlay markers and text
| |
− | itemdata = {}
| |
− | local colori = args['color'] or args['colour'] or 'red'
| |
− | local formi = ''
| |
− | for k = 1,#itemnums do
| |
− | local i = itemnums[k]
| |
− | formi = args['overlay' .. i .. 'form'] or formi
| |
− | colori = args['overlay' .. i .. 'color'] or args['overlay' .. i .. 'colour'] or colori
| |
− | local linki = args['overlay' .. i .. 'link'] or ''
| |
− | local tipi = args['overlay' .. i .. 'tip'] or args['overlay' .. i] or ''
| |
− | local overlayi = args['overlay' .. i] or args['overlay' .. i .. 'tip'] or ''
| |
− | if (overlayi ~= '' or tipi ~= '') then
| |
− | local imagei = buildicon(i, formi, linki, colori, tipi)
| |
− | itemdata[k] = buildlegenditem(imagei, args['overlay' .. i .. 'link'] or '', overlayi)
| |
− | end
| |
− | end
| |
− |
| |
− | -- create the overlay image
| |
− | if image ~= '' then
| |
− | local cell = root:tag('tr'):tag('td')
| |
− | cell:attr('align', 'center')
| |
− | if( padding ~= '' ) then
| |
− | cell:css('padding', padding)
| |
− | end
| |
− | if( columns > 1 and legendbox == 'yes' ) then
| |
− | cell:attr('colspan', columns)
| |
− | end
| |
− | local imagediv = cell:tag('div')
| |
− | imagediv:css('position','relative')
| |
− | :css('left', '0px')
| |
− | :css('top', '0px')
| |
− | :css('width', ((grid == 'yes') and 940 or width) .. 'px')
| |
− | :css('height', ((grid == 'yes') and 940 or height) .. 'px')
| |
− | if grid == 'yes' then
| |
− | imagediv:tag('span')
| |
− | :css('position', 'absolute')
| |
− | :css('left', '0px')
| |
− | :css('top', '0px')
| |
− | :css('z-index', '2')
| |
− | :wikitext('[[File:Grid 99, 100 int red 50 int yellow (940).svg|940px]]')
| |
− | end
| |
− | imagediv:tag('span')
| |
− | :css('position', 'absolute')
| |
− | :css('left', '0px')
| |
− | :css('top', '0px')
| |
− | :css('z-index', '0')
| |
− | :css('width', width .. 'px')
| |
− | :css('height', height .. 'px')
| |
− | :wikitext('[[File:' .. image .. '|' .. width .. 'x' .. height .. 'px]]')
| |
− | if overlay == 'yes' then
| |
− | for k = 1,#itemnums do
| |
− | local i = itemnums[k]
| |
− | local imagei = (itemdata[k])[1]
| |
− | for j =0,3 do
| |
− | local overlayileftj = args['overlay' .. i .. 'left' .. ((j == 0) and '' or j)] or ''
| |
− | local overlayitopj = args['overlay' .. i .. 'top' .. ((j == 0) and '' or j)] or ''
| |
− | if overlayileftj ~= '' then
| |
− | imagediv:tag('div')
| |
− | :css('position', 'absolute')
| |
− | :css('left', overlayileftj .. 'px')
| |
− | :css('top', overlayitopj .. 'px')
| |
− | :css('line-height', '95%')
| |
− | :css('z-index', '1')
| |
− | :wikitext(imagei)
| |
− | end
| |
− | end
| |
− | end
| |
− | end
| |
− | end
| |
− |
| |
− | -- Split the legend items into sub-legends
| |
− | legend = {{}, {}, {}, {}, {}}
| |
− | local jmax = itemnums[#itemnums]
| |
− | for i=1,5 do
| |
− | if args['legend' .. i .. 'start'] then
| |
− | -- default is all items
| |
− | j1 = 0
| |
− | j2 = jmax
| |
− | -- set start item number to (legendistart) or (legend(i-1)end + 1)
| |
− | if args['legend' .. i .. 'start'] then
| |
− | j1 = tonumber(args['legend' .. i .. 'start']) or j1
| |
− | elseif args['legend' .. (i-1) .. 'end'] then
| |
− | j1 = (tonumber(args['legend' .. (i-1) .. 'end']) or j1) + 1
| |
− | end
| |
− | -- set end item number to (legendiend) or (legend(i+1)start - 1)
| |
− | if args['legend' .. i .. 'end'] then
| |
− | j2 = tonumber(args['legend' .. i .. 'end']) or j2
| |
− | elseif args['legend' .. (i+1) .. 'start'] then
| |
− | j2 = (tonumber(args['legend' .. (i+1) .. 'start']) or j2) - 1
| |
− | end
| |
− | -- get the items within the range, marking them as they are used
| |
− | for k=1,#itemnums do
| |
− | j = itemnums[k]
| |
− | if (j >= 0 and j >= j1 and j <= j2) then
| |
− | table.insert(legend[i], itemdata[k])
| |
− | itemnums[k] = -1
| |
− | end
| |
− | end
| |
− | end
| |
− | end
| |
− |
| |
− | -- Add any left over items to the first legend
| |
− | for k = 1,#itemnums do
| |
− | if itemnums[k] >= 0 then
| |
− | table.insert(legend[1], itemdata[k])
| |
− | end
| |
− | end
| |
− |
| |
− | -- Build the legend
| |
− | if columns > 0 then
| |
− | for i = 1,5 do
| |
− | local locallegend = legend[i]
| |
− | if (locallegend and #locallegend > 0) then
| |
− | local cell = root:tag('tr'):tag('td')
| |
− | cell:wikitext(buildlegend(locallegend, columns, border, args['legend' .. i .. 'title'] or ''))
| |
− | end
| |
− | end
| |
− | end
| |
− |
| |
− | return tostring(root)
| |
− | end
| |
− |
| |
− | return p
| |