Modulo:Itemlist2
La documentazione per questo modulo può essere creata in Modulo:Itemlist2/man
local p = {}
local errors = {}
local getArgs = require('Module:Arguments').getArgs
-- Aggiunge tutti gli argomenti dal secondo in avanti alla tabella t
local function dump(t, ...)
local args = {...}
for _, s in ipairs(args) do
table.insert(t, s)
end
end
-- =================================================================
-- Classe per accumulare le liste di città raggruppate per titolo
-- =================================================================
local Title = {}
Title.__index = Title
function Title.new(title, listtype)
return setmetatable({
title = title or '',
dirty = true, -- la lista nomi deve essere ordinata prima della stampa
names_sorted = {}, -- lista di nomi delle città ordinati della stampa
names_fixed = {}, -- array di nomi di città che devono andare in posizione fissa, indicizzati per posizione
names_all = {}, -- lista nomi ordinati alfabeticamente + quelli in posizione fissa
cities = {}, -- array di dati aggiuntivi sulle città {alt, description, full name} indicizzati per nome città
listtype = listtype
}, Title)
end
function Title:sort()
-- non ordino se non necessario
if not self.dirty then return end
-- ordino la lista dei nomi di città
table.sort(self.names_sorted)
for _,name in ipairs(self.names_sorted) do
self.names_all[#self.names_all+1] = name
end
-- creo una lista delle posizioni fisse e la ordino
local positions = {}
for pos, _ in pairs(self.names_fixed) do
positions[#positions+1] = pos
end
table.sort(positions)
-- inserisco i nomi che vanno in posizione fissa nella lista ordinata
for _,pos in ipairs(positions) do
table.insert(self.names_all, math.min(pos, #self.names_all+1), self.names_fixed[pos])
end
self.dirty = false
end
function Title:add_item(name, alt, description, position, lat, long)
position = position or 0
local label
if position > 0 then
if self.names_fixed[position] ~=nil then
dump(errors, "Posizione " .. position .. " duplicata per città " .. self.names_fixed[position] .. " e " .. name)
return
end
label = name
self.names_fixed[position] = name
else
local wlink = mw.ustring.match(name, "^%[%[(.+)%]%]")
if wlink then
link, label = mw.ustring.match(wlink, "(.+)|(.*)")
if label == nil then
label = wlink
end
else
label = name
end
self.names_sorted[#self.names_sorted+1] = label
end
self.cities[label] = {alt, description, name, lat, long}
self.dirty = true
end
function Title.__tostring(self)
if self.dirty then self:sort() end
local answer = {}
if self.names_sorted == 0 then return '' end
if self.title ~= '' then dump(answer,";'''", self.title, "'''\n") end
local tipo = {
citylist = "city",
destinationlist = "vicinity"
}
for _,name in ipairs(self.names_all) do
local item = self.cities[name]
local output_name = item[3]
if item[4] and item[5] then
local frame = mw.getCurrentFrame():getParent() or mw.getCurrentFrame()
output_name = frame:expandTemplate{ title = 'User:Yurik/Marker', args = { tipo=tipo[self.listtype], nome=item[3], lat=item[4], long=item[5] } }
end
dump(answer, "*'''", output_name, "'''")
if item[1] ~= '' then dump(answer, " (", item[1], ")") end
if item[2] ~= '' then dump(answer, " — ", item[2]) end
dump(answer, "\n")
end
return table.concat(answer)
end
setmetatable(Title, { __call = function(_, ...) return Title.new(...) end })
-- =================================================================
-- Fine classe Title
-- =================================================================
local function item(frame)
local args = getArgs(frame)
local parameter_name = { 'titolo', 'nome', 'alt', 'pos', 'lat', 'long', 'descrizione'}
local return_values = {}
for _,p_name in ipairs(parameter_name) do
if args[p_name] then
return_values[#return_values+1] = string.format('<<%s>>%s<</%s>>', p_name, args[p_name], p_name)
end
end
return table.concat(return_values, ' ')
end
local function string2table(inputData)
local t = {}
for k, v in mw.ustring.gmatch(inputData, '<<(%w+)>>(.-)<</%1>>') do
t[k] = v
end
return t
end
local function itemlist(frame, listtype)
-- Se chiamata mediante #invoke, usa gli argomenti passati al template invocante.
-- Altrimenti a scopo di test assume che gli argomenti siano passati direttamente
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame.args
end
listtype = listtype or 'citylist'; -- teoricamente superflua, ma evito che chiamate errate (senza listtype) mandino in blocco questa funzione
local titles = {}
local end_loop = false
local first_title_done = false
local n = 1
local current_title = 1
-- Carico le variabili
while not end_loop do
local itemargs = origArgs[n]
local item = {}
local name
if itemargs ~= nil then
item = string2table(itemargs)
name = item.nome
end
if name ~= nil then
local title = item.titolo
if title ~= nil then
if first_title_done then current_title = current_title + 1 end
titles[current_title] = Title(title, listtype)
first_title_done = true
elseif not first_title_done then
titles[1] = Title('', listtype)
first_title_done = true
end
local alt = item.alt or ''
local description = item.descrizione or ''
local position_string = item.pos
if position_string ~= nil then
position = tonumber(position_string) or 0
if position == 0 then
dump(errors, "Il parametro 'pos' della città " .. name .. " non è un numero")
elseif position < 0 then
dump(errors, "Il parametro 'pos' della città " .. name .. " è zero o negativo")
else
position = math.floor(position)
end
else
position = 0
end
titles[current_title]:add_item(name, alt, description, position, item.lat, item.long)
else
if n > 20 then --controllo l'esistenza di almeno i primi 20 parametri
end_loop = true
end
end
n=n+1
end
-- se la lista di titoli ha lunghezza zero termino e ritorno stringa nulla
if #titles == 0 then return '' end
-- genero l'output
local reply = {}
for _,title in ipairs(titles) do
reply[#reply+1] = tostring(title)
end
if #reply == 0 then return '' end
if #errors>0 then
local current_page = mw.title.getCurrentTitle()
if current_page.namespace == 0 then
dump(reply, '[[Categoria:' .. listtype .. ' con errori di compilazione]]')
end
dump(reply, '<span class="' .. listtype .. 'info debuginfo" style="display:none;">\n' .. table.concat(errors, '; ') .. '</span>')
end
return '<div id="' .. listtype .. '">\n' .. table.concat(reply) .. '</div>'
end
function p.GetTitle(frame)
local t = frame2table(frame)
return t['titolo']
end
function p.GetName(frame)
local t = frame2table(frame)
return t['nome']
end
function p.GetAlt(frame)
local t = frame2table(frame)
return t['alt']
end
function p.GetPos(frame)
local t = frame2table(frame)
return t['pos']
end
function p.GetDescription(frame)
local t = frame2table(frame)
return t['descrizione']
end
function p.GetNameBold(frame)
local t = frame2table(frame)
if t['nome'] and #t['nome']>0 then t['nome'] = "'''" .. t['nome'] .. "'''" end
return t['nome']
end
function p.GetLat(frame)
local t = frame2table(frame)
return t['lat']
end
function p.GetLong(frame)
local t = frame2table(frame)
return t['long']
end
function frame2table(frame)
local t = {}
local args = getArgs(frame, {frameOnly=true})
local inputData = args[1] or ''
for k, v in mw.ustring.gmatch(inputData, '<<(%w+)>>(.-)<</%1>>') do
t[k] = v
end
return t
end
function p.cityitem(frame)
return item(frame, 'cityitem')
end
function p.destinationitem(frame)
return item(frame, 'destinationitem')
end
function p.citylist(frame)
return itemlist(frame, 'citylist')
end
function p.destinationlist(frame)
return itemlist(frame, 'destinationlist')
end
return p