--[[
Questo modulo è in appoggio al template Fumetto e animazione per gestirne
le funzioni di categorizzazione automatica
]]
local p = {}
local cfg = mw.loadData("Modulo:Fumetto e animazione/Configurazione/sandbox")
local getArgs = require('Module:Arguments').getArgs
local mDelink = require('Modulo:Delink')
local error_category = 'Errori di compilazione del template Fumetto e animazione'
local function build_reverse_alias(table_name)
local reverse_alias = {}
for alias, name in pairs(cfg['alias_' .. table_name]) do
if not reverse_alias[name] then reverse_alias[name] = {} end
table.insert(reverse_alias[name], alias)
end
return reverse_alias
end
-- ========================================================================
-- Sostituisce name con il suo alias se presente nella tabella alias
-- quindi ritorna il valore corrispondente dalla tabella values
-- ========================================================================
local function get_category(name, table_name, delink)
if name and delink then
-- Rimuove i wikilink e restituisce la parte a sinistra della barra in caso di pipe trick
name = name:match('^%[%[(.-)|.+%]%]') or name:match('^%[%[(.-)%]%]') or name
end
name = cfg['alias_' .. table_name][name] or name
return cfg[table_name][name]
end
-- ========================================================================
-- Rimpiazza le parentesi quadre nella stringa con i corrispondenti codici
-- ascii
-- ========================================================================
local function replace_braces(s)
local new_s = mw.ustring.gsub(s, "%[", "[")
new_s = mw.ustring.gsub(new_s, "%]", "]")
new_s = mw.ustring.gsub(new_s, "%(", "(")
new_s = mw.ustring.gsub(new_s, "%)", ")")
new_s = mw.ustring.gsub(new_s, " ", " ")
return new_s
end
-- ========================================================================
-- Appende una tabella a un'altra tabella
-- ========================================================================
local function append_table(t1, t2)
for _,el in ipairs(t2) do
t1[#t1+1] = el
end
end
-- ========================================================================
-- Restituisce l'aggettivo plurale maschile o femminile del Paese
-- specificato usando il template AggNaz
-- ========================================================================
local function get_adj(paese, genere)
local adj
local title = mw.title.new('Template:AggNaz/' .. paese)
adj = (title and title.exists) and
mw.getCurrentFrame():expandTemplate {
title = title.text,
args = { genere }
} or nil
return adj
end
-- ========================================================================
-- Restituisce il tipo di opera se riconosciuto nella configurazione
-- ========================================================================
local function get_media(args, alias)
local key_tipo = alias and 'prefisso_tipo' or 'tipo'
local key_sottotipo = alias and 'prefisso_sottotipo' or 'sottotipo'
local ret = cfg[key_sottotipo][args.tipo] and
cfg[key_sottotipo][args.tipo][args.sottotipo] or
cfg[key_tipo][args.tipo]
return ret and ret:lower() or nil
end
-- ========================================================================
-- Restituisce true se l'opera corrisponde a uno dei media indicati
-- ========================================================================
local function media_in_array(args, ...)
for _, media in ipairs({ ... }) do
media = media:gsub('^%l', string.upper)
if cfg.tipo[args.tipo] == media or
cfg.sottotipo[args.tipo] == media or
cfg.sottotipo[args.tipo][args.sottotipo] == media then
return true
end
end
return false
end
-- ========================================================================
-- Individua e restituisce un anno, se presente nella stringa indicata
-- ========================================================================
local function get_year(str)
if str then
return str:match('%d%d%d%d')
end
end
-- ========================================================================
-- Ritorna una lista di categorie per la sequenza di parametri con
-- nome base 'base_name' consultando la tabella 'table'.
-- 'alias_table' è una tabella di nomi alternativi per i valori dei
-- parametri, 'max_index' il numero massimo dell'indice del parametro
-- da controllare
-- ========================================================================
local function get_categories(args, table_name, lowercase)
local categories = {}
local base_name = table_name:match('[^_]')
local anno = get_year(args['data inizio']) or get_year(args['data fine'])
local index = 1
while true do
local adj
local name_value = args[base_name .. ' ' .. tostring(index)] or index == 1 and args[base_name]
if not name_value then break end
name_value = mDelink._main({ name_value })
if lowercase then name_value = mw.ustring.lower(name_value) end
if table_name == 'paese_TV' then
adj = get_adj(name_value, 'fp')
if adj and (adj ~= 'giapponesi' or args[base_name .. ' 2']) then
categories[#categories+1] = 'Serie televisive d\'animazione ' .. adj
end
elseif table_name == 'paese_film_DTV' then
adj = get_adj(name_value, 'mp')
if adj then
categories[#categories+1] = 'Film d\'animazione ' .. adj
if anno then
categories[#categories+1] = 'Film ' .. adj .. ' del ' .. anno
end
end
elseif table_name == 'paese_webserie' then
adj = get_adj(name_value, 'fp')
if adj then
categories[#categories+1] = 'Webserie ' .. adj
end
elseif table_name == 'paese_film_TV' then
adj = get_adj(name_value, 'mp')
if adj then
categories[#categories+1] = 'Film d\'animazione ' .. adj .. ' per la televisione'
end
elseif table_name == 'paese_fumetto' then
if name_value == 'Belgio' or name_value == 'Francia' then
categories[#categories+1] = 'Fumetti franco-belgi'
else
adj = get_adj(name_value, 'mp')
if adj and adj ~= 'giapponesi' and
adj ~= 'cinesi' and adj ~= 'coreani' then
categories[#categories+1] = 'Fumetti ' .. adj
end
end
elseif table_name == 'etichetta_sottotipo' or table_name == 'editore_sottotipo' then
categories[#categories+1] = get_category(args.sottotipo .. ' ' .. name_value, table_name)
else
local category = get_category(name_value, table_name)
if category then
categories[#categories+1] = category
end
end
index = index + 1
end
return categories
end
----------------------------------------------------------------------------------
-- Categorizza tranne che per genere
----------------------------------------------------------------------------------
function p.categorie(frame)
local args = getArgs(frame, {parentOnly = true})
local media = get_media(args)
local isMainspace = mw.title.getCurrentTitle().namespace == 0
local catEnabled = args.categorie ~= 'no'
if not (media and isMainspace and catEnabled) then return end
local categories = {}
local year = get_year(args['data inizio']) or get_year(args['data fine'])
-- Categoria di errore quando data inizio/data fine sono compilati
-- ma non si rilevano le quattro cifre dell'anno in entrambi
if (args['data inizio'] or args['data fine']) and not year then
categories[#categories+1] = error_category
end
-- Categorizzazioni specifiche
if media == "serie televisive d'animazione" then
append_table(categories, get_categories(args, 'studio_cartoneTV'))
if counter == #categories then
append_table(categories, get_categories(args, 'paese_TV'))
append_table(categories, get_categories(args, 'studio'))
end
elseif media_in_array(args, 'anime', 'cartone') then
if media == "film d'animazione direct-to-video" then
categories[#categories+1] = tipo
append_table(categories, get_categories(args, 'paese_film_DTV'))
elseif media == "webserie d'animazione" then
append_table(categories, get_categories(args, 'paese_webserie'))
elseif media == "film d'animazione per la televisione" then
append_table(categories, get_categories(args, 'paese_film_TV'))
end
append_table(categories, get_categories(args, 'studio'))
elseif args.tipo == 'manga' then
counter = #categories
append_table(categories, get_categories(args, 'editore_manga'))
if counter == #categories then
append_table(categories, get_categories(args, 'editore'))
end
elseif media_in_array(args, 'manhwa', 'manhua') then
append_table(categories, get_categories(args, 'editore'))
elseif args.tipo == 'light novel' then
categories[#categories+1] = tipo
if (args['lingua originale'] or ''):match('giapponese') then
categories[#categories+1] = 'Romanzi in giapponese'
end
counter = #categories
append_table(categories, get_categories(args, 'etichetta'))
if counter == #categories then
append_table(categories, get_categories(args, 'editore'))
end
elseif args.tipo == 'fumetto' then
counter = #categories
if args.sottotipo then
append_table(categories, get_categories(args, 'etichetta_sottotipo'))
end
if counter == #categories then
local etichetta = {}
etichetta = get_category(mDelink._main({ args.etichetta }), 'etichetta')
if etichetta then
append_table(categories, get_categories(args, 'etichetta'))
end
counter = #categories
if args.sottotipo then
append_table(categories, get_categories(args, 'editore_sottotipo'))
end
if counter == #categories then
if args.sottotipo then
categories[#categories+1] = tipo
end
if etichetta == nil then
counter = #categories
append_table(categories, get_categories(args, 'editore'))
if counter == #categories then
append_table(categories, get_categories(args, 'paese_fumetto'))
end
end
end
end
end
local emittente = get_category(args.streaming, 'streaming', true) or
args.streaming == nil and get_category(args.rete, 'rete', true)
if emittente and media_in_array('anime', 'cartone') then
local pre_emittente = get_media(args, true)
if pre_emittente then
if pre_emittente:find('^Webserie') and not args.streaming then
categories[#categories+1] = error_category
else
categories[#categories+1] = pre_emittente .. emittente
end
end
end
if media_in_array(args, 'manga', 'manhwa') then
append_table(categories, get_categories(args, 'target', true))
end
-- Categorizzazione per tipo delle opere non suddivise per anno
if media_in_array(args, 'manhua', 'manhwa', 'original net anime', "webserie d'animazione") then
categories[#categories+1] = media
-- Categorizzazione per anno delle opere previste
elseif year and args.sottotipo ~= 'film direct-to-video' then
categories[#categories+1] = string.format('%s del %s', get_media(args, true) or media, year)
end
for index, cat in ipairs(categories) do
categories[index] = '[[Categoria:' .. cat .. ']]'
end
return table.concat(categories)
end
----------------------------------------------------------------------------------
-- Gestisce categorie e wikilink dei generi
----------------------------------------------------------------------------------
function p.generi(frame)
local args = getArgs(frame, {parentOnly = not frame.args[1]})
local genre = frame.args[1]
if genre == '' then return end
local current_page = mw.title.getCurrentTitle()
local current_namespace = current_page.namespace
local category
local result = {}
for name, alias_name in pairs(cfg['alias_genere']) do
local piped = mw.ustring.match(genre, '%[%[[^%[]*|%s*' .. name .. '%s*%]%]')
local pattern = (piped and '%[%[[^%[]*|%s*' or '%[%[%s*') .. name .. '%s*%]%]%a*'
genre = mw.ustring.gsub( genre, pattern, '[[' .. alias_name .. ']]' )
end
for name, correct_name in pairs(cfg['genere']) do
if current_namespace == 0 and args.categorie ~= 'no' then
local tipo = {
['anime'] = correct_name[1],
['fumetto'] = correct_name[2],
['light novel'] = correct_name[3],
['manga'] = correct_name[1],
['manhua'] = correct_name[2],
['manhwa'] = correct_name[2]
}
tipo = tipo[args.tipo]
tipo = tipo and tipo[1] and tipo[1] .. ']][[Categoria:' .. tipo[2] or tipo
category = tipo and tipo ~= '' and '[[Categoria:' .. tipo .. ']]'
end
local piped = mw.ustring.match(genre, '%[%[[^%[]*|%s*' .. name .. '%s*%]%]')
local pattern = (piped and '%[%[[^%[]*|%s*' or '%[%[%s*') .. name .. '%s*%]%]%a*'
genre = mw.ustring.gsub( genre, pattern, correct_name[4] .. (category or '') )
-- Categoria d'errore in caso di genere senza corrispondenza
local list = mw.text.split( genre, ',' )
for i = 1, #list do
local s = replace_braces(list[i])
local p = replace_braces(correct_name[4])
if mw.ustring.match( s, p ) then
result[i] = ''
elseif result[i] == nil and current_namespace == 0 then
result[i] = '[[Categoria:' .. error_category .. ']]'
end
end
end
genre = genre .. table.concat(result)
return genre
end
----------------------------------------------------------------------------------
-- Ritorna la configurazione della tabella per aziende e target
----------------------------------------------------------------------------------
function p.tabella_configurazione(frame)
local args = getArgs(frame)
local table_name = args[1]
if not(table_name) then return '' end
local reverse_alias = build_reverse_alias(table_name)
local root = mw.html.create('table')
root
:addClass('wikitable mw-collapsible mw-collapsed sortable')
:tag('tr')
:tag('th'):wikitext(table_name):done()
:tag('th'):wikitext('Alias'):done()
:tag('th'):wikitext('Categoria'):done()
for name, cat_name in pairs(cfg[table_name]) do
local name_code = table_name == 'genere' and
replace_braces(cat_name[4]) or
'[[' .. name .. ']]'
local cat_code = {}
if cat_name[1] then
for i, cat in ipairs(cat_name) do
if i > 3 then break end
cat = cat[1] and
cat[1] .. ']]<br />[[:Categoria:' .. cat[2] or cat
if cat ~= '' then
cat_code[#cat_code+1] = '[[:Categoria:' .. cat .. ']]'
end
end
cat_code = table.concat(cat_code, '<br />')
else
cat_code = '[[:Categoria:' .. cat_name .. ']]'
end
local alias_code = ' '
if reverse_alias[name] then
for i,alias in ipairs(reverse_alias[name]) do
reverse_alias[name][i] = '[[' .. alias .. ']]'
end
alias_code = table.concat(reverse_alias[name], '<br />')
end
root:tag('tr')
:tag('td'):wikitext(name_code):done()
:tag('td'):wikitext(alias_code):done()
:tag('td'):wikitext(cat_code):done()
end
return tostring(root)
end
return p