Modulo:Bio
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Bio/man (modifica · cronologia)
Sandbox: Modulo:Bio/sandbox (modifica · cronologia) · Sottopagine: lista · Test: Modulo:Bio/test (modifica · cronologia · esegui)
Modulo Lua che implementa le funzionalità del Template:Bio.
Ha le seguenti sottopagine di configurazione:
- Configurazione: parametri di configurazione principali
- Link attività: tabella di conversione per il link all'attività
- Ex attivita: tabella contenente le attività ammesse col prefisso "ex"
- Link nazionalità: tabella di conversione per il link alla nazionalità
- Plurale attività: tabella di conversione per il plurale dell'attività
- Plurale nazionalità: tabella di conversione per il plurale della nazionalità
- Plurale attività genere: tabella di conversione da singolare maschile e femminile al plurale maschile e femminile
- Parametri: tabella per configurare i parametri accettati dal modulo e i rispettivi valori validi
- Cat luoghi: tabella di casi particolari per le categorie "Nati/morti a [luogo]"
Funzionamento interno
Lo schema seguente rappresenta l'ordine in cui vengono chiamate le principali funzioni, facendo riferimento a dei parametri di esempio:
{{Bio
|Nome = Giulia
|Cognome = Rossi
|Sesso = F
|LuogoNascita = Roma
|GiornoMeseNascita = 15 gennaio
|AnnoNascita = 1910
|LuogoMorte = Firenze
|GiornoMeseMorte = 15 febbraio
|AnnoMorte = 1990
|Attività = scienziata
|Nazionalità = italiana
}}
- main()
- ArgsParser:parse()
- CategoryManager:new()
- CategoryManager:_getPluralsAttivitaNazionalita() => ottiene "scienziati" via Modulo:Bio/Plurale attività e "italiani" via Modulo:Bio/Plurale nazionalità
- CategoryManager:_addAttivita() => Categoria:Scienziati italiani
- CategoryManager:_addNatiMorti() => Categoria:Nati nel 1910 Categoria:Morti nel 1990 Categoria:Nati il 15 gennaio Categoria:Morti il 15 febbraio Categoria:Nati a Roma Categoria:Morti a Firenze
- CategoryManager:_addCategoriesWikidata()
- Incipit:new()
- Incipit:_addImmagine()
- Incipit:_addNomeCognome() => Giulia Rossi
- Incipit:_addNascitaMorte() => (Roma, 15 gennaio 1910 – Firenze, 15 febbraio 1990)
- Incipit:_addAttivita() => è stata una scienziata italiana (ottiene "scienziato" via Modulo:Bio/Link attività, e "Italia" via Modulo:Bio/Link nazionalità)
--[[
* Modulo che implementa il template Bio.
*
* Nota: non esistendo in Lua una differenziazione tra metodi pubblici e privati,
* per convenzione, quelli privati iniziano con un underscore.
]]
require("strict")
local mString = require("Modulo:String")
local mWikidata = require("Modulo:Wikidata")
local cfg = mw.loadData("Modulo:Bio/Configurazione")
local ex_attivita = mw.loadData("Modulo:Bio/Ex attività")
-- argomenti passati al template
local args
-- table per contenere gli errori
local errorTable = {}
-- nomi dei parametri per l'attività e la nazionalità
local attivitaParams = { "Attività", "Attività2", "Attività3" }
local nazionalitaParams = { "Nazionalità", "NazionalitàNaturalizzato", "Cittadinanza" }
-- =============================================================================
-- Funzioni di utilità
-- =============================================================================
-- Aggiunge l'output del [[Template:Avviso]] e una categoria di warning a errorTable
local function addAvviso(testo, category)
local text
text = mw.getCurrentFrame():expandTemplate {
title = "Avviso",
args = {
tipo = "stile",
immagine = "[[File:Nuvola apps important.svg|40px]]",
["immagine a destra"] = "[[File:Crystal Clear app Login Manager.svg|40px]]",
testo = testo
}
}
table.insert(errorTable, text)
if mw.title.getCurrentTitle().namespace == 0 then
table.insert(errorTable, string.format("[[Categoria:%s]]\n", cfg.categorie[category]))
end
end
-- Wrapper di mw.title.exists, verifica sia che name sia valido, sia che esista
local function titleExists(name)
local title = mw.title.new(name)
return title and title.exists
end
local function currentTitleEquals(name)
local title = mw.title.getCurrentTitle().text
title = mw.text.split(title, " %(")[1]
return title == name or mw.getContentLanguage():lcfirst(title) == name
end
-- Se date inizia con "1 " o "1°" restituisce una nuova data che inizia per "1º", altrimenti date
local function fixFirstOfMonth(date)
date = date:gsub("^1%s", "1º ")
date = date:gsub("^1\194\176", "1º")
return date
end
-- Restituisce "ed" se nextWord inizia con "e", altrimenti "e"
local function getEufonica(nextWord)
return nextWord:match("^e[^d]") and "ed" or "e"
end
-- Restituisce true se uno degli argomenti del modulo specificati (params) ha almeno
-- un valore tra quelli indicati (values), altrimenti false
local function argsSearch(params, values)
local ret = false
for _, param in ipairs(params) do
for _, value in ipairs(values) do
if args[param] == value then
return true
end
end
end
return false
end
-- Riconosce le ex attività previste e le restituisce senza "ex"
local function isExAttivita(attivita)
local ret
attivita = attivita:match("^ex (.+)$")
if attivita then
for _, v in ipairs(ex_attivita) do
if v == attivita then
ret = attivita
break
end
end
end
return ret
end
-- =============================================================================
-- classe ArgsParser
-- =============================================================================
local ArgsParser = {}
function ArgsParser:new()
local self = {}
setmetatable(self, { __index = ArgsParser })
return self
end
-- Parsifica i parametri passati al modulo e aggiunge eventuali categorie di errore.
-- Restituisce i parametri conosciuti scartando quelli valorizzati a stringa vuota.
function ArgsParser:parse(origArgs)
local paramcfg = require("Modulo:Bio/Parametri")
local retArgs = {}
-- controlla i parametri conosciuti e li copia
for k, v in pairs(origArgs) do
if paramcfg.params[k] then
if v ~= "" then
retArgs[k] = v
end
else
addAvviso(cfg.warningParams.testo:gsub("$1", "il parametro '" ..
(tonumber(k) and (v == "" and " " or v) or k ) .. "' è sconosciuto"), "unknown-params")
end
end
-- controlla il valore
for i, validator in pairs(paramcfg.validators) do
if retArgs[validator.param] then
if not self:_checkParamValue(retArgs[validator.param], validator.valuetest, retArgs) then
if validator.errmsg then
addAvviso(cfg.warningParams.testo:gsub("$1", validator.errmsg), "wrong-params")
end
end
end
end
-- è ammessa l'iniziale maiuscola per i parametri per attività e nazionalità
-- (complicazione inutile. basta eliminare dalle voci le maiuscole esistenti)
local lang = mw.getContentLanguage()
for _, param in ipairs(attivitaParams) do
if retArgs[param] and not cfg.attivita_maiuscolo[retArgs[param]] then
retArgs[param] = lang:lcfirst(retArgs[param])
end
end
for _, param in ipairs(nazionalitaParams) do
retArgs[param] = retArgs[param] and lang:lcfirst(retArgs[param])
end
return retArgs
end
-- Utilizzata da parse per controllare il valore di un parametro.
-- Restituisce true se il valore è valido altrimenti false.
function ArgsParser:_checkParamValue(value, valueTest, otherArgs)
local ret = true
if type(valueTest) == "function" then
ret = valueTest(value, otherArgs)
elseif type(valueTest) == "string" and not value:match(valueTest) then
ret = false
end
return ret
end
-- =============================================================================
-- classe CategoryManager
-- =============================================================================
local CategoryManager = {}
function CategoryManager:new()
local self = {}
setmetatable(self, { __index = CategoryManager })
self.plurale_attivita = nil
self.plurale_nazionalita = nil
self.categories = {}
-- al di fuori del namespace 0 esegue comunque il controllo di attività e nazionalità
self.plurals = self:_getPluralsAttivitaNazionalita()
local title = mw.title.getCurrentTitle()
if title.namespace == 0 and title.text ~= 'Pagina principale' or args.Debug then
-- imposta la magic word defaultsort
local sortkey
if args.ForzaOrdinamento then
sortkey = args.ForzaOrdinamento:gsub("(.-)%s*,%s*(.*)", "%1 ,%2")
elseif args.Soprannome and args.Cognome and currentTitleEquals(args.Soprannome .. " " .. args.Cognome) then
sortkey = mString.collate( { args = { args.Cognome .. " ," .. args.Soprannome } } )
elseif args.Pseudonimo and currentTitleEquals(args.Pseudonimo) then
local pseudonimo = mString.collate( { args = { args.Pseudonimo } } )
if pseudonimo ~= args.Pseudonimo then
sortkey = pseudonimo
end
elseif args.Cognome and args.Nome then
sortkey = mString.collate( { args = { args.Cognome .. " ," .. args.Nome } } )
elseif args.Nome then
local nome = mString.collate( { args = { args.Nome } } )
if nome ~= args.Nome then
sortkey = nome
end
end
if sortkey then
if args.Debug then
-- per i test di DEFAULTSORT in Modulo:Bio/test
table.insert(self.categories, string.format("DEFAULTSORT:%s", sortkey))
else
mw.getCurrentFrame():preprocess("{{DEFAULTSORT:" .. sortkey .. "}}")
end
end
self:_addAttivita(self.plurals)
self:_addNatiMorti()
self:_addCategory(cfg.categorie["bot"])
-- categoria di servizio per AnnoMorte (o anno corrente) - AnnoNascita > 122
local years = {
birth = tonumber(args.AnnoNascita),
death = not args.AnnoMorte and os.date("%Y") or tonumber(args.AnnoMorte)
}
if years.birth and years.death and years.death - years.birth > 122 then
self:_addCategory(cfg.categorie["controllo-età"])
end
-- eventuali categorie di servizio per Wikidata
if not args.Debug then
self:_addCategoriesWikidata()
end
end
return self
end
function CategoryManager:getCategories()
return self.categories
end
function CategoryManager:_addCategory(cat)
table.insert(self.categories, string.format("[[Categoria:%s]]", cat))
end
-- Aggiunge la categoria se la pagina non ha un elemento Wikidata collegato,
-- oppure non ha la proprietà indicata.
function CategoryManager:_addCategoryWikidata(propertyId, cat)
if not mWikidata._getProperty({ propertyId }) then
self:_addCategory(cat)
end
end
-- Aggiunge eventuali categorie di servizio per Wikidata, tramite controlli
-- più avanzati di quelli che si effettuano abitualmente con {{Controllo Wikidata}}.
function CategoryManager:_addCategoriesWikidata()
-- Per Speciale:LinkPermanente/80165551#Proposta_categoria_di_servizio_biografie_con_data_di_morte_su_Wikidata
if not args.AnnoMorte and mWikidata._getProperty({ "P570" }) then
self:_addCategory("Voci con template Bio senza AnnoMorte ma con data di morte su Wikidata")
end
if mWikidata._instanceOf({ "Q5" }) then
-- Per Speciale:LinkPermanente/66620402#Add_this_text_to_Template:Bio
if args["Nazionalità"] then
self:_addCategoryWikidata("P27", "Voci con template Bio e nazionalità assente su Wikidata")
end
-- Per Speciale:LinkPermanente/80165551#Wikidata_d:Property:P21
if not args.Sesso or args.Sesso == "M" then
self:_addCategoryWikidata("P21", "Voci con template Bio e sesso (M) assente su Wikidata")
elseif args.Sesso == "F" then
self:_addCategoryWikidata("P21", "Voci con template Bio e sesso (F) assente su Wikidata")
end
-- Per Speciale:LinkPermanente/80254035#Wikidata_properties_P19.2C_P20.2C_P569.2C_P570
if args.LuogoNascita and not args.LuogoNascitaLink then
self:_addCategoryWikidata("P19", "Voci con template Bio e LuogoNascita assente su Wikidata")
end
if args.LuogoNascitaLink then
self:_addCategoryWikidata("P19", "Voci con template Bio e LuogoNascitaLink assente su Wikidata")
end
if args.LuogoMorte and not args.LuogoMorteLink then
self:_addCategoryWikidata("P20", "Voci con template Bio e LuogoMorte assente su Wikidata")
end
if args.LuogoMorteLink then
self:_addCategoryWikidata("P20", "Voci con template Bio e LuogoMorteLink assente su Wikidata")
end
if args.AnnoNascita then
self:_addCategoryWikidata("P569", "Voci con template Bio e AnnoNascita assente su Wikidata")
end
if args.AnnoMorte and args.AnnoMorte ~= "?" then
self:_addCategoryWikidata("P570", "Voci con template Bio e AnnoMorte assente su Wikidata")
end
if args.Immagine and not titleExists("File:" .. args.Immagine) then
self:_addCategoryWikidata("P18", "Voci con template Bio e Immagine assente su Wikidata")
end
-- Per Speciale:LinkPermanente/80336084#Wikidata_properties_P27
-- e Speciale:LinkPermanente/105389666#Year_in_line_278_(for_Wikidata_category)
local annoNascita = tonumber(args.AnnoNascita)
local annoMorte = tonumber(args.AnnoNascita)
if (args["Nazionalità"] == "italiano" or args["Nazionalità"] == "italiana") and
((annoNascita or 0) > 1861 or (annoMorte or 0) > 1861) then
-- Le cittadinanze "Italia" e "Regno d'Italia" non si escludono, quindi non va usato "elseif"
local cittadRegno = false
local cittadRepubblica = false
if ((annoNascita ~= nil and annoNascita < 1946) or (annoMorte ~= nil and annoMorte < 1946)) then
self:_addCategoryWikidata("P27", "Voci con template Bio e cittadinanza Regno d'Italia assente su Wikidata")
cittadRegno = true
end
if ((annoNascita or 0) > 1946 or (annoMorte or 0) > 1946) then
self:_addCategoryWikidata("P27", "Voci con template Bio e cittadinanza Italia assente su Wikidata")
cittadRepubblica = true
end
if not (cittadRegno or cittadRepubblica) then
self:_addCategoryWikidata("P27", "Voci con template Bio e Nazionalità italiana assente su Wikidata")
end
elseif args["Nazionalità"] == "statunitense" and
((annoNascita or 0) > 1776 or (annoMorte or 0) > 1776) then
self:_addCategoryWikidata("P27", "Voci con template Bio e Nazionalità statunitense assente su Wikidata")
elseif args["Nazionalità"] == "francese" and
((annoNascita or 0) > 1799 or (annoMorte or 0) > 1799) then
self:_addCategoryWikidata("P27", "Voci con template Bio e Nazionalità francese assente su Wikidata")
end
-- Per Speciale:LinkPermanente/80431600#Wikidata_properties_P106
if argsSearch(attivitaParams, { "calciatore", "ex calciatore", "calciatrice" }) then
self:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (calciatore)")
end
if argsSearch(attivitaParams, { "attore", "attrice" }) then
self:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (attore)")
end
if argsSearch(attivitaParams, { "politico", "politica" }) then
self:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (politico)")
end
end
end
-- Restituisce il plurale dell'attività o nil se non trovato (con eventuale warning)
function CategoryManager:_getPluralAttivita(attivita)
local plural
self.plurale_attivita = self.plurale_attivita or mw.loadData("Modulo:Bio/Plurale attività")
plural = self.plurale_attivita[isExAttivita(attivita) or attivita]
if not plural then
addAvviso(cfg.warningA.testo .. cfg.warningA.testo2a:gsub("$1", attivita) .. cfg.warningA.testo3, "warning")
end
return plural
end
-- Restituisce il plurale della nazionalità o nil se non trovato (con eventuale warning)
function CategoryManager:_getPluralNazionalita(nazionalita)
local plural
self.plurale_nazionalita = self.plurale_nazionalita or mw.loadData("Modulo:Bio/Plurale nazionalità")
plural = self.plurale_nazionalita[nazionalita]
if not plural then
addAvviso(cfg.warningN.testo .. cfg.warningN.testo2a:gsub("$1", nazionalita) .. cfg.warningN.testo3, "warning")
end
return plural
end
-- Restituisce il plurale dei parametri necessari per le categorie
function CategoryManager:_getPluralsAttivitaNazionalita()
local plurals = {}
local attnaznecessarie = not (args.Categorie == "no" and args.FineIncipit)
-- Nazionalità può essere vuota solo quando c'è Categorie=no e FineIncipit
if not args["Nazionalità"] and attnaznecessarie then
addAvviso(cfg.warningN.testo .. cfg.warningN.testo2b .. cfg.warningN.testo3, "warning")
end
for _, nazionalita in ipairs(nazionalitaParams) do
if args[nazionalita] then
plurals[nazionalita] = self:_getPluralNazionalita(args[nazionalita])
end
end
-- Attività può essere vuota solo quando c'è Categorie=no e FineIncipit
if not args["Attività"] and attnaznecessarie then
addAvviso(cfg.warningA.testo .. cfg.warningA.testo2b .. cfg.warningA.testo3, "warning")
end
for _, attivita in ipairs(attivitaParams) do
if args[attivita] then
plurals[attivita] = self:_getPluralAttivita(args[attivita])
end
end
return plurals
end
-- Calcola il valore di Epoca se non inserito dall'utente.
function CategoryManager:_getEpoca()
local ret
local annoNascita = tonumber(args.AnnoNascita)
local annoMorte = tonumber(args.AnnoMorte)
if not annoNascita then
annoNascita = args.AnnoNascita:match('^(%d+) a%.C%.$')
annoNascita = annoNascita and tonumber(annoNascita) * -1
end
if annoNascita and annoNascita >= 2000 then
return "2000"
end
if not annoMorte and args.AnnoMorte then
annoMorte = args.AnnoMorte:match('^(%d+) a%.C%.$')
annoMorte = annoMorte and tonumber(annoMorte) * -1
end
if annoNascita and annoMorte and
annoNascita >= -500 and annoNascita <= 2100 and
annoMorte >= -500 and annoMorte <= 2100 and
((annoNascita >= 0 and annoMorte >= 0) or (annoNascita < 0 and annoMorte < 0)) then
local sign = ''
if annoNascita < 0 then
annoNascita, annoMorte = -annoNascita, -annoMorte
sign = '-'
end
local secoloNascita = math.floor((annoNascita - 1) / 100) * 100
local secoloMorte = math.floor((annoMorte - 1) / 100) * 100
ret = secoloNascita == secoloMorte and (sign .. secoloNascita) or nil
end
return ret
end
-- Aggiunge Categoria:X dei secoli, se esistono
function CategoryManager:_addCatSecolo(catname, epoca1, epoca2)
local ok = false
for _, epoca in ipairs({ epoca1, epoca2 }) do
if epoca and titleExists("Categoria:" .. catname .. " " .. epoca) then
self:_addCategory(catname .. " " .. epoca)
ok = true
end
end
return ok
end
-- Aggiunge le categorie: Attività nazionalità [del XYZ secolo]
function CategoryManager:_addAttivita(plurals)
local catname, epoca1, epoca2, added, addatt, addnaz, add1, nazmonosec, addmonosec
addatt = {}
addnaz = {}
nazmonosec = {"cecoslovacchi", "jugoslavi", "sovietici"}
-- se Epoca e Epoca2 non sono stati inseriti dall'utente
-- e AnnoNascita e AnnoMorte cadono nello stesso secolo
-- calcola epoca1 automaticamente
if not args.Epoca and not args.Epoca2 and args.AnnoNascita then
epoca1 = self:_getEpoca()
epoca1 = epoca1 and cfg.epoche[epoca1]
else
epoca1 = args.Epoca and cfg.epoche[args.Epoca]
epoca2 = args.Epoca2 and cfg.epoche[args.Epoca2]
end
if not epoca1 and not epoca2 then
self:_addCategory(cfg.categorie["no-epoca"])
end
if args.Categorie ~= "no" then
for _, attivita in ipairs(attivitaParams) do
if plurals[attivita] then
for _, nazionalita in ipairs(nazionalitaParams) do
if plurals[nazionalita] then
catname = plurals[attivita] .. " " .. plurals[nazionalita]
added = self:_addCatSecolo(catname, epoca1, epoca2)
-- se non è stata aggiunta la categoria per epoca1 e epoca2
-- aggiunge la cat. semplice, es. "Scrittori italiani"
if added then
add1 = true
addatt[attivita] = true
addnaz[nazionalita] = true
else
self:_addCategory(catname)
for _, v in ipairs(nazmonosec) do -- pezza per naz. monosecolo
if plurals[nazionalita] == v then
addmonosec = true
end
end
end
end
end
end
end
end
-- in mancanza di "A N del S" prova "A del S" e "N del S"
for _, attivita in ipairs(attivitaParams) do
if plurals[attivita] and not addatt[attivita] then
add1 = self:_addCatSecolo(plurals[attivita], epoca1, epoca2) or add1
end
end
for _, nazionalita in ipairs(nazionalitaParams) do
if plurals[nazionalita] and not addnaz[nazionalita] then
add1 = self:_addCatSecolo(plurals[nazionalita], epoca1, epoca2) or add1
for _, v in ipairs(nazmonosec) do -- pezza per naz. monosecolo
if plurals[nazionalita] == v and not add1 and not addmonosec then
self:_addCategory(plurals[nazionalita])
add1 = true
end
end
end
end
if not add1 and not addmonosec then
self:_addCatSecolo("Persone", epoca1, epoca2)
end
end
-- Utilizzata da addNatiMorti, restituisce il nome della categoria
-- se titleLink o title sono nella lista di eccezioni Cat luoghi, altrimenti nil
function CategoryManager:_getCatLuoghi(titleLink, title, catPrefix)
local cat
self.catLuoghi = self.catLuoghi or mw.loadData("Modulo:Bio/Cat luoghi")
if titleLink and title then
cat = self.catLuoghi[titleLink]
elseif title then
cat = self.catLuoghi[title]
end
return cat and (catPrefix .. " " .. cat) or nil
end
-- Aggiunge le categorie: Nati/Morti nell'anno/giorno/luogo
function CategoryManager:_addNatiMorti()
local cat1, cat2
if args.AnnoNascita then
cat1 = "Nati nel " .. args.AnnoNascita
cat2 = "Nati nell'" .. args.AnnoNascita
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
if args.AnnoMorte then
if args.AnnoMorte == "?" then
self:_addCategory(cfg.categorie["annomorte-punto-interrogativo"])
else
cat1 = "Morti nel " .. args.AnnoMorte
cat2 = "Morti nell'" .. args.AnnoMorte
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
else
self:_addCategory(cfg.categorie["annomorte-assente"])
end
if args.GiornoMeseNascita then
cat1 = "Nati il " .. fixFirstOfMonth(args.GiornoMeseNascita)
cat2 = "Nati l'" .. args.GiornoMeseNascita
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
if args.GiornoMeseMorte then
cat1 = "Morti il " .. fixFirstOfMonth(args.GiornoMeseMorte)
cat2 = "Morti l'" .. args.GiornoMeseMorte
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
-- prima di verificare le categorie per LuogoNascitaLink e LuogoNascita
-- viene controllata una lista di eccezioni
cat1 = self:_getCatLuoghi(args.LuogoNascitaLink, args.LuogoNascita, "Nati")
if cat1 then
self:_addCategory(cat1)
elseif args.LuogoNascitaLink then
cat1 = "Nati a " .. args.LuogoNascitaLink
cat2 = "Nati ad " .. args.LuogoNascitaLink
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
elseif args.LuogoNascita then
cat1 = "Nati a " .. args.LuogoNascita
cat2 = "Nati ad " .. args.LuogoNascita
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
-- prima di verificare le categorie per LuogoMorteLink e LuogoMorte
-- viene controllata una lista di eccezioni
cat1 = self:_getCatLuoghi(args.LuogoMorteLink, args.LuogoMorte, "Morti")
if cat1 then
self:_addCategory(cat1)
elseif args.LuogoMorteLink then
cat1 = "Morti a " .. args.LuogoMorteLink
cat2 = "Morti ad " .. args.LuogoMorteLink
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
elseif args.LuogoMorte then
cat1 = "Morti a " .. args.LuogoMorte
cat2 = "Morti ad " .. args.LuogoMorte
if titleExists("Categoria:" .. cat1) then
self:_addCategory(cat1)
elseif titleExists("Categoria:" .. cat2) then
self:_addCategory(cat2)
end
end
end
-- =============================================================================
-- classe Incipit
-- =============================================================================
local Incipit = {}
function Incipit:new()
local self = {}
setmetatable(self, { __index = Incipit })
self.textTable = {}
self:_addImmagine()
self:_addNomeCognome()
self:_addNascitaMorte()
if args.Soprannome or args.Pseudonimo or args.PostCognomeVirgola then
self:_addText(",")
end
if args.FineIncipit then
if self:_needSpace(args.FineIncipit) then
self:_addText(' ')
end
self:_addText(args.FineIncipit)
else
self:_addAttivita()
end
if args.Punto ~= "no" then
self:_addText((args.FineIncipit == "e" or
args.FineIncipit == "ed" or
args.FineIncipit == ",") and
" " or ".")
end
return self
end
function Incipit:getIncipit()
return table.concat(self.textTable)
end
-- Aggiunge testo alla risposta, svolge anche la funzione di concatenatore
function Incipit:_addText(...)
local arg = {...}
for _, val in ipairs(arg) do
table.insert(self.textTable, val)
end
end
-- Aggiunge un wlink alla risposta, se target è nil utilizza label come target.
-- labelPrefix, se presente, viene rimosso dalla label e anteposto al wlink.
function Incipit:_addWlink(target, label, labelPrefix)
if target and label and labelPrefix then
local count
label, count = label:gsub("^" .. labelPrefix .. " ", "")
if count == 1 then
self:_addText(labelPrefix, " ")
end
end
if target and label then
self:_addText("[[", target, "|", label, "]]")
else
self:_addText("[[", target or label, "]]")
end
end
-- Aggiunge una immagine alla risposta, size e caption sono opzionali
function Incipit:_addImage(name, size, caption)
self:_addText("[[File:", name, "|thumb")
if size then
self:_addText("|", size, "px")
end
if caption then
self:_addText("|", caption)
end
self:_addText("]]", "\n")
end
-- Restituisce true se text necessita di uno spazio iniziale (PostCognome, PostSoprannome, PostPseudonimo, LuogoNascitaAlt, NoteNascita, LuogoMorteAlt, NoteMorte, AttivitàAltre, PostNazionalità, FineIncipit)
function Incipit:_needSpace(text)
return mw.ustring.match(mw.ustring.sub(text, 1, 1), "%w") ~= nil or
text:sub(1, 2) == "[[" or
text:sub(1, 1) == "(" or
text:sub(1, 1) == "'" or
mw.ustring.sub(text, 1, 1) == "–" or
text:sub(1, 5) == "<span"
end
function Incipit:_getArticleMan(attivita)
local article
if cfg.articoli_maschili["uno"][attivita] then
article = "uno"
elseif cfg.articoli_maschili["una"][attivita] then
article = "una"
else
article = "un"
end
return article
end
function Incipit:_getArticleWoman(attivita)
local article
-- aggiunge anche uno spazio nel caso non usi l'apostrofo
if cfg.articoli_femminili["un"][attivita] then
article = "un "
elseif attivita and attivita:match("^[aeiou]") then
article = "un'"
else
article = "una "
end
return article
end
function Incipit:_addImmagine()
local caption
if args.Immagine then
if args.Didascalia then
caption = args.Didascalia
elseif args.Pseudonimo and currentTitleEquals(args.Pseudonimo) then
caption = args.Pseudonimo
elseif args.Soprannome and args.Cognome and currentTitleEquals(args.Soprannome .. " " .. args.Cognome) then
caption = args.Soprannome .. " " .. args.Cognome
elseif args.Soprannome and currentTitleEquals(args.Soprannome) then
caption = args.Soprannome
else
if args.CognomePrima and args.Nome and args.Cognome then
caption = args.Cognome .. " " .. args.Nome
else
if args.Nome then
caption = args.Nome
end
if args.Cognome then
caption = (caption or "") .. " " .. args.Cognome
end
end
end
if args.Didascalia2 then
caption = (caption or "") .. "<hr />" .. args.Didascalia2
end
self:_addImage(args.Immagine, args.DimImmagine, caption)
elseif args.Didascalia2 then
-- parentesi () extra per non restituire anche il gsub.count
self:_addText( (cfg.didascalia2:gsub("$1", args.Didascalia2)) )
end
end
function Incipit:_addNomeCognome()
if args.Titolo then
self:_addText(args.Titolo, " ")
end
if args.Pseudonimo and currentTitleEquals(args.Pseudonimo) then
self:_addText("'''", args.Pseudonimo, "'''")
if args.PostPseudonimo then
if self:_needSpace(args.PostPseudonimo) then
self:_addText(" ")
end
self:_addText(args.PostPseudonimo)
end
self:_addText(", pseudonimo di ")
end
-- inizio grassetto
self:_addText("'''")
if args.CognomePrima and args.Nome and args.Cognome then
self:_addText(args.Cognome, " ", args.Nome, mw.getCurrentFrame():expandTemplate{
title = "Nota nome",
args = { [1] = args.CognomePrima, [2] = args.Cognome }
})
else
local no_space
if args.Nome then
self:_addText(args.Nome)
-- niente spazio prima di Cognome se Nome termina con «d'»
no_space = mw.ustring.match(args.Nome, " d'$") and ''
end
if args.Cognome then
self:_addText(no_space or " ", args.Cognome)
end
end
-- fine grassetto
self:_addText("'''")
if args.PostCognomeVirgola then
self:_addText(", ", args.PostCognomeVirgola)
elseif args.PostCognome then
if self:_needSpace(args.PostCognome) then
self:_addText(" ")
end
self:_addText(args.PostCognome)
end
if args.Soprannome then
self:_addText(", ", (not args.Sesso or args.Sesso == "M") and "detto" or "detta",
" ", "'''", args.Soprannome, "'''")
if args.PostSoprannome then
if self:_needSpace(args.PostSoprannome) then
self:_addText(" ")
end
self:_addText(args.PostSoprannome)
end
end
if args.Pseudonimo and not currentTitleEquals(args.Pseudonimo) then
self:_addText(", ", (not args.Sesso or args.Sesso == "M") and "noto" or "nota",
" anche con lo pseudonimo di ", "'''", args.Pseudonimo, "'''")
if args.PostPseudonimo then
if self:_needSpace(args.PostPseudonimo) then
self:_addText(" ")
end
self:_addText(args.PostPseudonimo)
end
end
end
function Incipit:_addNascitaMorte()
-- si apre la parentesi
self:_addText(" (")
if args.PreData then
self:_addText(args.PreData, "; ")
end
local datimancanti = not (args.LuogoNascita or args.GiornoMeseNascita or args.AnnoNascita or args.NoteNascita or args.LuogoMorte or args.GiornoMeseMorte)
local floruit = args.AnnoMorte == "?" and (args.Floruit or cfg.epoche[args.Epoca])
if args.LuogoNascita then
self:_addWlink(args.LuogoNascitaLink, args.LuogoNascita)
if args.LuogoNascitaAlt then
if self:_needSpace(args.LuogoNascitaAlt) then
self:_addText(" ")
end
self:_addText(args.LuogoNascitaAlt)
end
self:_addText(", ")
end
if args.GiornoMeseNascita then
if titleExists(args.GiornoMeseNascita) then
self:_addWlink(args.GiornoMeseNascita)
else
self:_addText(args.GiornoMeseNascita)
end
self:_addText(" ")
end
if args.AnnoNascita then
if titleExists(args.AnnoNascita) then
self:_addWlink(args.AnnoNascita)
else
self:_addText(args.AnnoNascita)
end
elseif not floruit or not datimancanti then
self:_addText("...")
end
if args.NoteNascita then
if self:_needSpace(args.NoteNascita) then
self:_addText(" ")
end
self:_addText(args.NoteNascita)
end
if args.AnnoMorte and (not floruit or not datimancanti) then
self:_addText(" – ")
if args.LuogoMorte then
self:_addWlink(args.LuogoMorteLink, args.LuogoMorte)
if args.LuogoMorteAlt then
if self:_needSpace(args.LuogoMorteAlt) then
self:_addText(" ")
end
self:_addText(args.LuogoMorteAlt)
end
self:_addText(", ")
end
if args.GiornoMeseMorte then
if titleExists(args.GiornoMeseMorte) then
self:_addWlink(args.GiornoMeseMorte)
else
self:_addText(args.GiornoMeseMorte)
end
self:_addText(" ")
end
if args.AnnoMorte then
if args.AnnoMorte == "?" then
self:_addText("...")
else
if titleExists(args.AnnoMorte) then
self:_addWlink(args.AnnoMorte)
else
self:_addText(args.AnnoMorte)
end
end
end
end
-- se date ignote, usa Floruit o lo ricava da Epoca
if not args.AnnoNascita and args.AnnoMorte == "?" then
local fl = args.Floruit
if not fl and cfg.epoche[args.Epoca] then
fl = mw.ustring.gsub(cfg.epoche[args.Epoca], "^del ?l?'?", "")
-- se due epoche, le mette entrambe senza ripetere la parola "secolo"
if cfg.epoche[args.Epoca2] then
if fl ~= "I secolo a.C." then
fl = fl .. "|" .. mw.ustring.gsub(fl, " secolo.*$", "")
end
fl = "[[" .. fl .. "]]-[[" .. mw.ustring.gsub(cfg.epoche[args.Epoca2], "^del ?l?'?", "") .. "]]"
end
end
if fl then
if titleExists(fl) then
fl = "[[" .. fl .. "]]"
end
if not datimancanti then
self:_addText("; ")
end
self:_addText("[[floruit|fl.]] ", fl)
end
end
if args.NoteMorte then
if self:_needSpace(args.NoteMorte) then
self:_addText(" ")
end
self:_addText(args.NoteMorte)
end
-- si chiude la parentesi
self:_addText(")")
end
function Incipit:_addAttivita()
local link_attivita = mw.loadData("Modulo:Bio/Link attività")
local link_nazionalita = mw.loadData("Modulo:Bio/Link nazionalità")
self:_addText(" ")
if args["PreAttività"] then
self:_addText(args["PreAttività"], " ")
else
self:_addText("è ")
if args.AnnoMorte then
self:_addText((not args.Sesso or args.Sesso == "M")
and "stato " or "stata ")
end
if not args.Sesso or args.Sesso == "M" then
self:_addText(self:_getArticleMan(args["Attività"]), " ")
else
self:_addText(self:_getArticleWoman(args["Attività"]))
end
end
local getLinkAttivita = function(attivita)
if not attivita then return end
local ex_attivita = isExAttivita(attivita)
return link_attivita[ex_attivita or attivita] or ex_attivita
end
self:_addWlink(getLinkAttivita(args["Attività"]), args["Attività"] or "", "ex")
if args["Attività2"] then
if args["Attività3"] or args["AttivitàAltre"] then
self:_addText(",")
else
self:_addText(" ", getEufonica(args["Attività2"]))
end
self:_addText(" ")
self:_addWlink(getLinkAttivita(args["Attività2"]), args["Attività2"], "ex")
end
if args["Attività3"] then
if args["AttivitàAltre"] then
self:_addText(",")
else
self:_addText(" ", getEufonica(args["Attività3"]))
end
self:_addText(" ")
self:_addWlink(getLinkAttivita(args["Attività3"]), args["Attività3"], "ex")
end
if args["AttivitàAltre"] then
if self:_needSpace(args["AttivitàAltre"]) then
self:_addText(" ")
end
self:_addText(args["AttivitàAltre"])
end
self:_addText(" ")
self:_addWlink(link_nazionalita[args["Nazionalità"]], args["Nazionalità"] or "")
if args.Cittadinanza then
self:_addText(" con cittadinanza ")
self:_addWlink(link_nazionalita[args.Cittadinanza], args.Cittadinanza)
end
if args["NazionalitàNaturalizzato"] then
self:_addText(" ")
self:_addWlink("Naturalizzazione",
(not args.Sesso or args.Sesso == "M" or
(args.Sesso == "F" and self:_getArticleWoman(args["Attività"]) == "un ")) and
"naturalizzato" or "naturalizzata")
self:_addText(" ")
self:_addWlink(link_nazionalita[args["NazionalitàNaturalizzato"]], args["NazionalitàNaturalizzato"])
end
if args["PostNazionalità"] then
if self:_needSpace(args["PostNazionalità"]) then
self:_addText(" ")
end
self:_addText(args["PostNazionalità"])
end
end
-- =============================================================================
-- Funzioni esportate
-- =============================================================================
local p = {}
-- Funzione per {{#invoke:Bio|categorie}} utilizzato da Modulo:Bio/test
function p.categorie(frame)
args = ArgsParser:new():parse(frame.args)
local categories = CategoryManager:new():getCategories()
return table.concat(errorTable) ..
(args.Debug and ( table.concat(categories, '<br />'):gsub('%[%[', '[[:') ) .. '<br />' or
table.concat(categories))
end
-- Funzione per il template per {{Bio}}
function p.main(frame)
-- gli errori generano avvisi, ma non interrompono l'esecuzione,
-- come avveniva nel vecchio template.
args = ArgsParser:new():parse(frame:getParent().args)
local catTable = CategoryManager:new():getCategories()
return table.concat(errorTable) ..
Incipit:new():getIncipit() ..
table.concat(catTable)
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.