Modul:Rediger tabel
Udseende
-- et modul til at ændre indholdet eller udseendet af en tabel i en wikiartikel
-- der findes i øjeblikket fire tilgængelige funktioner:
-- procentkolonne, sletkolonne, sortertabel, ombytkolonner
local p = {}
local function inlist (name, list)
for n in mw.text.gsplit(list, '%s*,%s*') do
if n == name then return true end
end
return false
end
local function konstruer_tabel (args)
local tabel = ''
local start = true
for key, arg in pairs(args) do
if tonumber(key) then
if not start then
tabel = tabel..'|'..arg
else
tabel = arg
start = false
end
end
end
tabel = mw.text.trim(tabel)
return tabel
end
local function opdel_tabel_i_raekker (tabel)
local rowtabel = {}
local k, i = 1, 1
local row, rowtotal
-- find første række:
k = string.find(tabel,"^|%-%s*\n|.-\n|%-")
if k then
row = string.match(tabel,"^|%-%s*\n(|.-)\n|%-")
rowtabel[1] = row
i = 2
k = k + 3
else
error("Inputtet skal starte med: |-", 0)
end
-- find de næste rækker:
repeat row = string.match(tabel,"\n|%-%s*\n(|.-)\n|%-", k)
if row then
rowtabel[i] = row
i = i+1
k = string.find(tabel,"\n|%-%s*\n|.-\n|%-",k) + 3
end
until not row
local rk = i - 1 -- antal rækker
-- find sidste række:
row = string.match(tabel,"\n|%-%s*\n(|.-)$", k )
if row then
rowtabel[i] = row
rk = i
end
return rowtabel, rk
end
function celler_i_tabel(rowtabel)
local i,j,k,l,c,m = 0,0,0,0,0,0
celletabel = {}
local celle
-- find indholdet af cellerne
for key, row in pairs(rowtabel) do
celletabel[key] = {}
k = 1 -- position 1
c = 1 -- celle 1
repeat
i = string.find(row,'|[^\n]-||',k)
if i ~= k then
j = string.find(row,'|.-\n',k)
end
if i ~= k and j ~= k then
m = string.find(row,'|.-$',k)
end
if i==k then
celle = string.match(row,'|([^\n]-)||',k)
l = k + string.len(celle) + 2
if string.match(celle,'|') then
local attribut = string.match(celle,'(.-)|')
local indhold = string.match(celle,'|(.+)')
table.insert(celletabel[key], { ['attribut'] = attribut, ['indhold'] = indhold } )
else
local indhold = celle
table.insert(celletabel[key], { ['indhold'] = indhold } )
end
elseif j==k then -- sidste celle på linjen med linjeskift
celle = string.match(row,'|(.-)\n',k)
l = k + string.len(celle) + 2
if string.match(celle,'|') then
local attribut = string.match(celle,'(.-)|')
local indhold = string.match(celle,'|(.+)')
local ctabel = { ['attribut'] = attribut, ['indhold'] = indhold, ['lskift'] = true }
table.insert(celletabel[key], ctabel )
else
local indhold = celle
table.insert(celletabel[key], { ['indhold'] = indhold, ['lskift'] = true } )
end
elseif m==k then -- sidste celle på linjen og i rækken
celle = string.match(row,'|(.-)$',k)
l = k + string.len(celle) + 2
if string.match(celle,'|') then
local attribut = string.match(celle,'(.-)|')
local indhold = string.match(celle,'|(.+)')
table.insert(celletabel[key], { ['attribut'] = attribut, ['indhold'] = indhold } )
else
local indhold = celle
table.insert(celletabel[key], { ['indhold'] = indhold } )
end
else
error('Der er noget galt nær række '..key, 0)
end
c = c + 1
k = l
until l>string.len(row) or ((not i) and (not j) and (not m))
end
local kol = c - 1 -- antal kolonner
return celletabel, kol
end
local function laes_tabel (args)
local tabel = konstruer_tabel(args)
local rowtabel, rk = opdel_tabel_i_raekker(tabel)
rk = tonumber(args["antal talrækker"]) or tonumber(rk)
if not rk then
error('Skabelonen kan ikke fastslå antallet af rækker', 0)
end
local celletabel, kol = celler_i_tabel(rowtabel)
kol = tonumber(args["totalt antal kolonner"]) or tonumber(kol)
if not kol then
error('Skabelonen kan ikke fastslå antallet af kolonner', 0)
end
return celletabel, rk, kol
end
function p.procentkolonne (frame)
p.frame = frame
local args
if frame == mw.getCurrentFrame() then
args = frame:getParent().args
else
args = frame.args
end
local frakol = tonumber(args.frakolonne)
local tilkol = tonumber(args.tilkolonne)
local procentkol = tonumber(args.procentkolonne)
if not (procentkol and tilkol and frakol) then
error("Der mangler en eller flere af parametrene: ''frakolonne'', ''tilkolonne'', ''procentkolonne''", 0)
end
local celletabel, rk, kol = laes_tabel(args)
local tester = args.test or ''
local decimaler = mw.text.trim(args.decimaler or '0')
decimaler = tostring(math.floor(tonumber(decimaler) or 0))
local tilkoltal, frakoltal
local wikitext = ''
for row = 1, rk do
for col = 1, kol do
if col == 1 then wikitext = wikitext..'|-\n|'
else
if celletabel[row][col-1] and celletabel[row][col-1].lskift then
wikitext = wikitext .. '|'
else
wikitext = wikitext .. '||'
end
end
if celletabel[row][col] and celletabel[row][col].attribut then
wikitext = wikitext .. celletabel[row][col].attribut .. '|'
end
if celletabel[row][col] and celletabel[row][col].indhold then
if tester~='ja' and procentkol and frakol and tilkol and col==procentkol then
tilkoltal = celletabel[row][tilkol].indhold
frakoltal = celletabel[row][frakol].indhold
tilkoltal = string.gsub(tilkoltal, '%.', '')
frakoltal = string.gsub(frakoltal, '%.', '')
local tal = 100 * (tilkoltal - frakoltal) / frakoltal
tal = string.format('%.'..decimaler..'f', tal)
if tonumber(tal) > 0 then tal = '+'..tal end
tal = string.gsub(tal, '%.', ',')
wikitext = wikitext .. ' ' .. tal .. '% '
else
wikitext = wikitext .. celletabel[row][col].indhold
end
end
if celletabel[row][col] and celletabel[row][col].lskift then
wikitext = wikitext .. '\n'
end
if col==kol and row<rk then wikitext=wikitext..'\n' end
end
end
return wikitext
end
function p.sletkolonne (frame)
p.frame = frame
local args
if frame == mw.getCurrentFrame() then
args = frame:getParent().args
else
args = frame.args
end
local celletabel, rk, kol = laes_tabel(args)
local sletkolonne = args.sletkolonne
local tester = args.test or ''
local wikitext = ''
for row = 1, rk do
for col = 1, kol do
if not sletkolonne or not inlist(tostring(col), sletkolonne ) then
if col == 1 then wikitext = wikitext..'|-\n|'
else
if celletabel[row][col-1] and celletabel[row][col-1].lskift then
wikitext = wikitext .. '|'
else
wikitext = wikitext .. '||'
end
end
if celletabel[row][col] and celletabel[row][col].attribut then
wikitext = wikitext .. celletabel[row][col].attribut .. '|'
end
if celletabel[row][col] and celletabel[row][col].indhold then
wikitext = wikitext .. celletabel[row][col].indhold
end
if celletabel[row][col] and celletabel[row][col].lskift then
wikitext = wikitext .. '\n'
end
if col==kol and row<rk then wikitext=wikitext..'\n' end
end
end
end
return wikitext
end
function p.sortertabel (frame)
p.frame = frame
local args
if frame == mw.getCurrentFrame() then
args = frame:getParent().args
else
args = frame.args
end
local celletabel, rk, kol = laes_tabel(args)
local nrkolonne = tonumber(args.nrkolonne)
local kolonne = tonumber(args.sorterkolonne)
if not kolonne then error('Parameter "sorterkolonne" mangler eller er ikke et tal', 0) end
local alfabetisk = args.alfabetisk or ''
local stigende = args.stigende or ''
local tester = args.test or ''
args = nil -- bruger mindre memory
table.sort(celletabel, function (a,b)
local x = a[kolonne].indhold
local y = b[kolonne].indhold
if alfabetisk ~= 'ja' then
x = string.gsub(x, '%%', '') -- fjern procenttegn
x = string.gsub(x, '%.', '') -- fjern tusindadskiller
x = string.gsub(x, ',', '.') -- erstat decimalkomma med punktum
x = tonumber(x)
y = string.gsub(y, '%%', '')
y = string.gsub(y, '%.', '')
y = string.gsub(y, ',', '.')
y = tonumber(y)
end
if not x or not y then error('Det lykkedes ikke skabelonen at læse kolonne '..kolonne..' som tal. Sæt evt. parameter alfabetisk=ja', 0) end
if stigende == 'ja' then
return x < y
else
return x > y
end
end)
local gentag = 0
local linjetabel = {}
for row = 1, rk do
for col = 1, kol do
if col == 1 then
linjetabel[row] = '|-\n|'
else
if celletabel[row][col-1] and celletabel[row][col-1].lskift then
linjetabel[row] = linjetabel[row] .. '|'
else
linjetabel[row] = linjetabel[row] .. '||'
end
end
if celletabel[row][col] and celletabel[row][col].attribut then
linjetabel[row] = linjetabel[row] .. tostring(celletabel[row][col].attribut) .. '|'
end
if celletabel[row][col] and celletabel[row][col].indhold then
if nrkolonne and nrkolonne == col then
if row > 1 and celletabel[row][kolonne].indhold == celletabel[row-1][kolonne].indhold then
if gentag == 0 then gentag = row - 1 end
linjetabel[row] = linjetabel[row]..' '..tostring(gentag)..' ' -- samme rangering som forrige række
else
linjetabel[row] = linjetabel[row] .. ' ' .. tostring(row) .. ' '
gentag = 0
end
else
linjetabel[row] = linjetabel[row] .. tostring(celletabel[row][col].indhold)
end
end
if celletabel[row][col] and celletabel[row][col].lskift then
linjetabel[row] = linjetabel[row] .. '\n'
end
end
end
return table.concat(linjetabel,'\n')
end
function p.ombytkolonner (frame)
p.frame = frame
local args
if frame == mw.getCurrentFrame() then
args = frame:getParent().args
else
args = frame.args
end
local celletabel, rk, kol = laes_tabel(args)
local kolonneA = tonumber(args.kolonneA)
if not kolonneA then error('Parameter "kolonneA" mangler eller er ikke et tal', 0) end
local kolonneB = tonumber(args.kolonneB)
if not kolonneB then error('Parameter "kolonneB" mangler eller er ikke et tal', 0) end
local tester = args.test or ''
local wikitext = ''
for row = 1, rk do
for col = 1, kol do
if col == 1 then wikitext = wikitext..'|-\n|'
else
if celletabel[row][col-1] and celletabel[row][col-1].lskift then
wikitext = wikitext .. '|'
else
wikitext = wikitext .. '||'
end
end
if col ~= kolonneA and col ~= kolonneB then
if celletabel[row][col] and celletabel[row][col].attribut then
wikitext = wikitext .. celletabel[row][col].attribut .. '|'
end
if celletabel[row][col] and celletabel[row][col].indhold then
wikitext = wikitext .. celletabel[row][col].indhold
end
elseif col == kolonneA then
if celletabel[row][kolonneB] and celletabel[row][kolonneB].attribut then
wikitext = wikitext .. celletabel[row][kolonneB].attribut .. '|'
end
if celletabel[row][kolonneB] and celletabel[row][kolonneB].indhold then
wikitext = wikitext .. celletabel[row][kolonneB].indhold
end
else -- col = kolonneB
if celletabel[row][kolonneA] and celletabel[row][kolonneA].attribut then
wikitext = wikitext .. celletabel[row][kolonneA].attribut .. '|'
end
if celletabel[row][kolonneA] and celletabel[row][kolonneA].indhold then
wikitext = wikitext .. celletabel[row][kolonneA].indhold
end
end
if celletabel[row][col] and celletabel[row][col].lskift then
wikitext = wikitext .. '\n'
end
if col==kol and row<rk then wikitext=wikitext..'\n' end
end
end
return wikitext
end
return p