Questa pagina è protetta dallo spostamento
Questa pagina è protetta

Modulo:Bio

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazioneVai alla ricerca

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}}

--[[* 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 templatelocal args-- table per contenere gli errorilocal 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 errorTablelocal function addAvviso(testo, category)local texttext = 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 thentable.insert(errorTable, string.format("[[Categoria:%s]]\n", cfg.categorie[category]))endend-- Wrapper di mw.title.exists, verifica sia che name sia valido, sia che esistalocal function titleExists(name)local title = mw.title.new(name)return title and title.existsendlocal function currentTitleEquals(name)local title = mw.title.getCurrentTitle().texttitle = mw.text.split(title, " %(")[1]return title == name or mw.getContentLanguage():lcfirst(title) == nameend-- Se date inizia con "1 " o "1°" restituisce una nuova data che inizia per "1º", altrimenti datelocal function fixFirstOfMonth(date)date = date:gsub("^1%s", "1º ")date = date:gsub("^1\194\176", "1º")return dateend-- 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 falselocal function argsSearch(params, values)local ret = falsefor _, param in ipairs(params) dofor _, value in ipairs(values) doif args[param] == value thenreturn trueendendendreturn falseend-- Riconosce le ex attività previste e le restituisce senza "ex"local function isExAttivita(attivita)local retattivita = attivita:match("^ex (.+)$")if attivita thenfor _, v in ipairs(ex_attivita) doif v == attivita thenret = attivitabreakendendendreturn retend-- =============================================================================--                           classe ArgsParser-- =============================================================================local ArgsParser = {}function ArgsParser:new()local self = {}setmetatable(self, { __index = ArgsParser })return selfend-- 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 copiafor k, v in pairs(origArgs) doif paramcfg.params[k] thenif v ~= "" thenretArgs[k] = vendelseaddAvviso(cfg.warningParams.testo:gsub("$1", "il parametro '" ..  (tonumber(k) and (v == "" and " " or v) or k ) .. "' è sconosciuto"), "unknown-params")endend-- controlla il valorefor i, validator in pairs(paramcfg.validators) doif retArgs[validator.param] thenif not self:_checkParamValue(retArgs[validator.param], validator.valuetest, retArgs) thenif validator.errmsg thenaddAvviso(cfg.warningParams.testo:gsub("$1", validator.errmsg), "wrong-params")endendendend-- è 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) doif retArgs[param] and not cfg.attivita_maiuscolo[retArgs[param]] thenretArgs[param] = lang:lcfirst(retArgs[param])endendfor _, param in ipairs(nazionalitaParams) doretArgs[param] = retArgs[param] and lang:lcfirst(retArgs[param])endreturn retArgsend-- 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 = trueif type(valueTest) == "function" thenret = valueTest(value, otherArgs)elseif type(valueTest) == "string" and not value:match(valueTest) thenret = falseendreturn retend-- =============================================================================--                           classe CategoryManager-- =============================================================================local CategoryManager = {}function CategoryManager:new()local self = {}setmetatable(self, { __index = CategoryManager })self.plurale_attivita = nilself.plurale_nazionalita = nilself.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 defaultsortlocal sortkeyif args.ForzaOrdinamento thensortkey = args.ForzaOrdinamento:gsub("(.-)%s*,%s*(.*)", "%1 ,%2")elseif args.Soprannome and args.Cognome and currentTitleEquals(args.Soprannome .. " " .. args.Cognome) thensortkey = mString.collate( { args = { args.Cognome .. " ," .. args.Soprannome } } )elseif args.Pseudonimo and currentTitleEquals(args.Pseudonimo) thenlocal pseudonimo = mString.collate( { args = { args.Pseudonimo } } )if pseudonimo ~= args.Pseudonimo thensortkey = pseudonimoendelseif args.Cognome and args.Nome thensortkey = mString.collate( { args = { args.Cognome .. " ," .. args.Nome } } )elseif args.Nome thenlocal nome = mString.collate( { args = { args.Nome } } )if nome ~= args.Nome thensortkey = nomeendendif sortkey thenif args.Debug then-- per i test di DEFAULTSORT in Modulo:Bio/testtable.insert(self.categories, string.format("DEFAULTSORT:%s", sortkey))elsemw.getCurrentFrame():preprocess("{{DEFAULTSORT:" .. sortkey .. "}}")endendself:_addAttivita(self.plurals)self:_addNatiMorti()self:_addCategory(cfg.categorie["bot"])-- categoria di servizio per AnnoMorte (o anno corrente) - AnnoNascita > 122local 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 thenself:_addCategory(cfg.categorie["controllo-età"])end-- eventuali categorie di servizio per Wikidataif not args.Debug thenself:_addCategoriesWikidata()endendreturn selfendfunction CategoryManager:getCategories()return self.categoriesendfunction 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 }) thenself:_addCategory(cat)endend-- 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_Wikidataif not args.AnnoMorte and mWikidata._getProperty({ "P570" }) thenself:_addCategory("Voci con template Bio senza AnnoMorte ma con data di morte su Wikidata")endif mWikidata._instanceOf({ "Q5" }) then-- Per Speciale:LinkPermanente/66620402#Add_this_text_to_Template:Bioif args["Nazionalità"] thenself:_addCategoryWikidata("P27", "Voci con template Bio e nazionalità assente su Wikidata")end-- Per Speciale:LinkPermanente/80165551#Wikidata_d:Property:P21if not args.Sesso or args.Sesso == "M" thenself:_addCategoryWikidata("P21", "Voci con template Bio e sesso (M) assente su Wikidata")elseif args.Sesso == "F" thenself:_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_P570if args.LuogoNascita and not args.LuogoNascitaLink thenself:_addCategoryWikidata("P19", "Voci con template Bio e LuogoNascita assente su Wikidata")endif args.LuogoNascitaLink thenself:_addCategoryWikidata("P19", "Voci con template Bio e LuogoNascitaLink assente su Wikidata")endif args.LuogoMorte and not args.LuogoMorteLink thenself:_addCategoryWikidata("P20", "Voci con template Bio e LuogoMorte assente su Wikidata")endif args.LuogoMorteLink thenself:_addCategoryWikidata("P20", "Voci con template Bio e LuogoMorteLink assente su Wikidata")endif args.AnnoNascita thenself:_addCategoryWikidata("P569", "Voci con template Bio e AnnoNascita assente su Wikidata")endif args.AnnoMorte and args.AnnoMorte ~= "?" thenself:_addCategoryWikidata("P570", "Voci con template Bio e AnnoMorte assente su Wikidata")endif args.Immagine and not titleExists("File:" .. args.Immagine) thenself:_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 = falselocal 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   endif not (cittadRegno or cittadRepubblica) then   self:_addCategoryWikidata("P27", "Voci con template Bio e Nazionalità italiana assente su Wikidata")   endelseif 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_P106if argsSearch(attivitaParams, { "calciatore", "ex calciatore", "calciatrice" }) thenself:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (calciatore)")endif argsSearch(attivitaParams, { "attore", "attrice" }) thenself:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (attore)")endif argsSearch(attivitaParams, { "politico", "politica" }) thenself:_addCategoryWikidata("P106", "Voci con template Bio e Attività assente su Wikidata (politico)")endendend-- Restituisce il plurale dell'attività o nil se non trovato (con eventuale warning)function CategoryManager:_getPluralAttivita(attivita)local pluralself.plurale_attivita = self.plurale_attivita or mw.loadData("Modulo:Bio/Plurale attività")plural = self.plurale_attivita[isExAttivita(attivita) or attivita]if not plural thenaddAvviso(cfg.warningA.testo .. cfg.warningA.testo2a:gsub("$1", attivita) .. cfg.warningA.testo3, "warning")endreturn pluralend-- Restituisce il plurale della nazionalità o nil se non trovato (con eventuale warning)function CategoryManager:_getPluralNazionalita(nazionalita)local pluralself.plurale_nazionalita = self.plurale_nazionalita or mw.loadData("Modulo:Bio/Plurale nazionalità")plural = self.plurale_nazionalita[nazionalita]if not plural thenaddAvviso(cfg.warningN.testo .. cfg.warningN.testo2a:gsub("$1", nazionalita) .. cfg.warningN.testo3, "warning")endreturn pluralend-- Restituisce il plurale dei parametri necessari per le categoriefunction CategoryManager:_getPluralsAttivitaNazionalita()local plurals = {}local attnaznecessarie = not (args.Categorie == "no" and args.FineIncipit)-- Nazionalità può essere vuota solo quando c'è Categorie=no e FineIncipitif not args["Nazionalità"] and attnaznecessarie thenaddAvviso(cfg.warningN.testo .. cfg.warningN.testo2b .. cfg.warningN.testo3, "warning")endfor _, nazionalita in ipairs(nazionalitaParams) doif args[nazionalita] thenplurals[nazionalita] = self:_getPluralNazionalita(args[nazionalita])endend-- Attività può essere vuota solo quando c'è Categorie=no e FineIncipitif not args["Attività"] and attnaznecessarie thenaddAvviso(cfg.warningA.testo .. cfg.warningA.testo2b .. cfg.warningA.testo3, "warning")endfor _, attivita in ipairs(attivitaParams) doif args[attivita] thenplurals[attivita] = self:_getPluralAttivita(args[attivita])endendreturn pluralsend-- Calcola il valore di Epoca se non inserito dall'utente.function CategoryManager:_getEpoca()local retlocal annoNascita = tonumber(args.AnnoNascita)local annoMorte = tonumber(args.AnnoMorte)if not annoNascita thenannoNascita = args.AnnoNascita:match('^(%d+) a%.C%.$')annoNascita = annoNascita and tonumber(annoNascita) * -1endif annoNascita and annoNascita >= 2000 thenreturn "2000"endif not annoMorte and args.AnnoMorte thenannoMorte = args.AnnoMorte:match('^(%d+) a%.C%.$')annoMorte = annoMorte and tonumber(annoMorte) * -1endif 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 = '-'    endlocal secoloNascita = math.floor((annoNascita - 1) / 100) * 100local secoloMorte = math.floor((annoMorte - 1) / 100) * 100ret = secoloNascita == secoloMorte and (sign .. secoloNascita) or nilendreturn retend-- Aggiunge Categoria:X dei secoli, se esistonofunction CategoryManager:_addCatSecolo(catname, epoca1, epoca2)local ok = falsefor _, epoca in ipairs({ epoca1, epoca2 }) doif epoca and titleExists("Categoria:" .. catname .. " " .. epoca) thenself:_addCategory(catname .. " " .. epoca)ok = trueendendreturn okend-- Aggiunge le categorie: Attività nazionalità [del XYZ secolo]function CategoryManager:_addAttivita(plurals)local catname, epoca1, epoca2, added, addatt, addnaz, add1addatt = {}addnaz = {}-- se Epoca e Epoca2 non sono stati inseriti dall'utente-- e AnnoNascita e AnnoMorte cadono nello stesso secolo-- calcola epoca1 automaticamenteif not args.Epoca and not args.Epoca2 and args.AnnoNascita thenepoca1 = self:_getEpoca()epoca1 = epoca1 and cfg.epoche[epoca1]elseepoca1 = args.Epoca and cfg.epoche[args.Epoca]epoca2 = args.Epoca2 and cfg.epoche[args.Epoca2]endif not epoca1 and not epoca2 thenself:_addCategory(cfg.categorie["no-epoca"])endif args.Categorie ~= "no" thenfor _, attivita in ipairs(attivitaParams) doif plurals[attivita] thenfor _, nazionalita in ipairs(nazionalitaParams) doif plurals[nazionalita] thencatname = 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 thenadd1 = trueaddatt[attivita] = trueaddnaz[nazionalita] = trueelseself:_addCategory(catname)endendendendendend-- in mancanza di "A N del S" prova "A del S" e "N del S"for _, attivita in ipairs(attivitaParams) doif plurals[attivita] and not addatt[attivita] thenadd1 = self:_addCatSecolo(plurals[attivita], epoca1, epoca2) or add1endendfor _, nazionalita in ipairs(nazionalitaParams) doif plurals[nazionalita] and not addnaz[nazionalita] thenadd1 = self:_addCatSecolo(plurals[nazionalita], epoca1, epoca2) or add1endendif not add1 thenself:_addCatSecolo("Persone", epoca1, epoca2)endend-- Utilizzata da addNatiMorti, restituisce il nome della categoria-- se titleLink o title sono nella lista di eccezioni Cat luoghi, altrimenti nilfunction CategoryManager:_getCatLuoghi(titleLink, title, catPrefix)local catself.catLuoghi = self.catLuoghi or mw.loadData("Modulo:Bio/Cat luoghi")if titleLink and title thencat = self.catLuoghi[titleLink]elseif title thencat = self.catLuoghi[title]endreturn cat and (catPrefix .. " " .. cat) or nilend-- Aggiunge le categorie: Nati/Morti nell'anno/giorno/luogofunction CategoryManager:_addNatiMorti()local cat1, cat2if args.AnnoNascita thencat1 = "Nati nel " .. args.AnnoNascitacat2 = "Nati nell'" .. args.AnnoNascitaif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endendif args.AnnoMorte thenif args.AnnoMorte == "?" thenself:_addCategory(cfg.categorie["annomorte-punto-interrogativo"])elsecat1 = "Morti nel " .. args.AnnoMortecat2 = "Morti nell'" .. args.AnnoMorteif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endendelseself:_addCategory(cfg.categorie["annomorte-assente"])endif args.GiornoMeseNascita thencat1 = "Nati il " .. fixFirstOfMonth(args.GiornoMeseNascita)cat2 = "Nati l'" .. args.GiornoMeseNascitaif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)end   endif args.GiornoMeseMorte thencat1 = "Morti il " .. fixFirstOfMonth(args.GiornoMeseMorte)cat2 = "Morti l'" .. args.GiornoMeseMorteif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)end   end-- prima di verificare le categorie per LuogoNascitaLink e LuogoNascita-- viene controllata una lista di eccezionicat1 = self:_getCatLuoghi(args.LuogoNascitaLink, args.LuogoNascita, "Nati")if cat1 thenself:_addCategory(cat1)elseif args.LuogoNascitaLink thencat1 = "Nati a " .. args.LuogoNascitaLinkcat2 = "Nati ad " .. args.LuogoNascitaLinkif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endelseif args.LuogoNascita thencat1 = "Nati a " .. args.LuogoNascitacat2 = "Nati ad " .. args.LuogoNascitaif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endend-- prima di verificare le categorie per LuogoMorteLink e LuogoMorte-- viene controllata una lista di eccezionicat1 = self:_getCatLuoghi(args.LuogoMorteLink, args.LuogoMorte, "Morti")if cat1 thenself:_addCategory(cat1)elseif args.LuogoMorteLink thencat1 = "Morti a " .. args.LuogoMorteLinkcat2 = "Morti ad " .. args.LuogoMorteLinkif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endelseif args.LuogoMorte thencat1 = "Morti a " .. args.LuogoMortecat2 = "Morti ad " .. args.LuogoMorteif titleExists("Categoria:" .. cat1) thenself:_addCategory(cat1)elseif titleExists("Categoria:" .. cat2) thenself:_addCategory(cat2)endendend-- =============================================================================--                           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 thenself:_addText(",")endif args.FineIncipit thenif self:_needSpace(args.FineIncipit) thenself:_addText(' ')endself:_addText(args.FineIncipit)elseself:_addAttivita()endif args.Punto ~= "no" thenself:_addText((args.FineIncipit == "e" or  args.FineIncipit == "ed" or   args.FineIncipit == ",") and  " " or ".")endreturn selfendfunction Incipit:getIncipit()return table.concat(self.textTable)end-- Aggiunge testo alla risposta, svolge anche la funzione di concatenatorefunction Incipit:_addText(...)local arg = {...}for _, val in ipairs(arg) dotable.insert(self.textTable, val)endend-- 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 thenlocal countlabel, count = label:gsub("^" .. labelPrefix .. " ", "")if count == 1 thenself:_addText(labelPrefix, " ")endendif target and label thenself:_addText("[[", target, "|", label, "]]")elseself:_addText("[[", target or label, "]]")endend-- Aggiunge una immagine alla risposta, size e caption sono opzionalifunction Incipit:_addImage(name, size, caption)self:_addText("[[File:", name, "|thumb")if size thenself:_addText("|", size, "px")endif caption thenself:_addText("|", caption)endself:_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"endfunction Incipit:_getArticleMan(attivita)local articleif cfg.articoli_maschili["uno"][attivita] thenarticle = "uno"elseif cfg.articoli_maschili["una"][attivita] thenarticle = "una"elsearticle = "un"endreturn articleendfunction Incipit:_getArticleWoman(attivita)local article-- aggiunge anche uno spazio nel caso non usi l'apostrofoif cfg.articoli_femminili["un"][attivita] thenarticle = "un "elseif attivita and attivita:match("^[aeiou]") thenarticle = "un'"elsearticle = "una "endreturn articleendfunction Incipit:_addImmagine()local captionif args.Immagine thenif args.Didascalia thencaption = args.Didascaliaelseif args.Pseudonimo and currentTitleEquals(args.Pseudonimo) thencaption = args.Pseudonimoelseif args.Soprannome and args.Cognome and currentTitleEquals(args.Soprannome .. " " .. args.Cognome) thencaption = args.Soprannome .. " " .. args.Cognomeelseif args.Soprannome and currentTitleEquals(args.Soprannome) thencaption = args.Soprannomeelseif args.CognomePrima and args.Nome and args.Cognome thencaption = args.Cognome .. " " .. args.Nomeelseif args.Nome thencaption = args.Nomeendif args.Cognome thencaption = (caption or "") .. " " .. args.Cognomeendendendif args.Didascalia2 thencaption = (caption or "") .. "<hr />" .. args.Didascalia2endself:_addImage(args.Immagine, args.DimImmagine, caption)elseif args.Didascalia2 then-- parentesi () extra per non restituire anche il gsub.countself:_addText( (cfg.didascalia2:gsub("$1", args.Didascalia2)) )endendfunction Incipit:_addNomeCognome()if args.Titolo thenself:_addText(args.Titolo, " ")endif args.Pseudonimo and currentTitleEquals(args.Pseudonimo) thenself:_addText("'''", args.Pseudonimo, "'''")if args.PostPseudonimo thenif self:_needSpace(args.PostPseudonimo) thenself:_addText(" ")endself:_addText(args.PostPseudonimo)endself:_addText(", pseudonimo di ")endlocal soprannomecognome = args.Soprannomeif args.Soprannome and args.Cognome thensoprannomecognome = args.Soprannome .. " " .. args.Cognomeendif soprannomecognome and currentTitleEquals(soprannomecognome) thenself:_addText("'''", soprannomecognome, "'''")if args.PostSoprannome thenif self:_needSpace(args.PostSoprannome) thenself:_addText(" ")endself:_addText(args.PostSoprannome)endself:_addText(", vero nome ")end-- inizio grassettoself:_addText("'''")if args.CognomePrima and args.Nome and args.Cognome thenself:_addText(args.Cognome, " ", args.Nome, mw.getCurrentFrame():expandTemplate{title = "Nota nome",args = { [1] = args.CognomePrima, [2] = args.Cognome }})elselocal no_spaceif args.Nome thenself:_addText(args.Nome)-- niente spazio prima di Cognome se Nome termina con «d'»no_space = mw.ustring.match(args.Nome, " d'$") and ''endif args.Cognome thenself:_addText(no_space or " ", args.Cognome)endend-- fine grassettoself:_addText("'''")if args.PostCognomeVirgola thenself:_addText(", ", args.PostCognomeVirgola)elseif args.PostCognome thenif self:_needSpace(args.PostCognome) thenself:_addText(" ")endself:_addText(args.PostCognome)endif soprannomecognome and not currentTitleEquals(soprannomecognome) thenself:_addText(", ", (not args.Sesso or args.Sesso == "M") and "detto" or "detta",  " ", "'''", args.Soprannome, "'''")if args.PostSoprannome thenif self:_needSpace(args.PostSoprannome) thenself:_addText(" ")endself:_addText(args.PostSoprannome)endendif args.Pseudonimo and not currentTitleEquals(args.Pseudonimo) thenself:_addText(", ", (not args.Sesso or args.Sesso == "M") and "noto" or "nota",  " anche con lo pseudonimo di ", "'''", args.Pseudonimo, "'''")if args.PostPseudonimo thenif self:_needSpace(args.PostPseudonimo) thenself:_addText(" ")endself:_addText(args.PostPseudonimo)endendendfunction Incipit:_addNascitaMorte()-- si apre la parentesiself:_addText(" (")if args.PreData then self:_addText(args.PreData, "; ")endif args.LuogoNascita thenself:_addWlink(args.LuogoNascitaLink, args.LuogoNascita)if args.LuogoNascitaAlt thenif self:_needSpace(args.LuogoNascitaAlt) thenself:_addText(" ")endself:_addText(args.LuogoNascitaAlt)endself:_addText(", ")endif args.GiornoMeseNascita thenif titleExists(args.GiornoMeseNascita) thenself:_addWlink(args.GiornoMeseNascita)elseself:_addText(args.GiornoMeseNascita)endself:_addText(" ")endif args.AnnoNascita thenif titleExists(args.AnnoNascita) thenself:_addWlink(args.AnnoNascita)elseself:_addText(args.AnnoNascita)endelseself:_addText("...")endif args.NoteNascita thenif self:_needSpace(args.NoteNascita) thenself:_addText(" ")endself:_addText(args.NoteNascita)endif args.AnnoMorte thenself:_addText(" – ")if args.LuogoMorte thenself:_addWlink(args.LuogoMorteLink, args.LuogoMorte)if args.LuogoMorteAlt thenif self:_needSpace(args.LuogoMorteAlt) thenself:_addText(" ")endself:_addText(args.LuogoMorteAlt)endself:_addText(", ")endif args.GiornoMeseMorte thenif titleExists(args.GiornoMeseMorte) thenself:_addWlink(args.GiornoMeseMorte)elseself:_addText(args.GiornoMeseMorte)endself:_addText(" ")endif args.AnnoMorte thenif args.AnnoMorte == "?" thenself:_addText("...")elseif titleExists(args.AnnoMorte) thenself:_addWlink(args.AnnoMorte)elseself:_addText(args.AnnoMorte)endendendend-- se date ignote, usa Floruit o lo ricava da Epocaif not args.AnnoNascita and args.AnnoMorte == "?" thenlocal fl = args.Floruitif not fl and cfg.epoche[args.Epoca] thenfl = 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] thenif fl ~= "I secolo a.C." thenfl = fl .. "|" .. mw.ustring.gsub(fl, " secolo.*$", "")endfl = "[[" .. fl .. "]]-[[" .. mw.ustring.gsub(cfg.epoche[args.Epoca2], "^del ?l?'?", "") .. "]]"endendif fl thenif titleExists(fl) thenfl = "[[" .. fl .. "]]"endself:_addText("; [[floruit|fl.]] ", fl)endendif args.NoteMorte thenif self:_needSpace(args.NoteMorte) thenself:_addText(" ")endself:_addText(args.NoteMorte)end-- si chiude la parentesiself:_addText(")")endfunction 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à"] thenself:_addText(args["PreAttività"], " ")elseself:_addText("è ")if args.AnnoMorte thenself:_addText((not args.Sesso or args.Sesso == "M") and "stato " or "stata ")endif not args.Sesso or args.Sesso == "M" thenself:_addText(self:_getArticleMan(args["Attività"]), " ")elseself:_addText(self:_getArticleWoman(args["Attività"]))endendlocal getLinkAttivita = function(attivita)if not attivita then return endlocal ex_attivita = isExAttivita(attivita)return link_attivita[ex_attivita or attivita] or ex_attivitaendself:_addWlink(getLinkAttivita(args["Attività"]), args["Attività"] or "", "ex")if args["Attività2"] thenif args["Attività3"] or args["AttivitàAltre"] thenself:_addText(",")elseself:_addText(" ", getEufonica(args["Attività2"]))endself:_addText(" ")self:_addWlink(getLinkAttivita(args["Attività2"]), args["Attività2"], "ex")endif args["Attività3"] thenif args["AttivitàAltre"] thenself:_addText(",")elseself:_addText(" ", getEufonica(args["Attività3"]))endself:_addText(" ")self:_addWlink(getLinkAttivita(args["Attività3"]), args["Attività3"], "ex")endif args["AttivitàAltre"] thenif self:_needSpace(args["AttivitàAltre"]) thenself:_addText(" ")endself:_addText(args["AttivitàAltre"])endself:_addText(" ")self:_addWlink(link_nazionalita[args["Nazionalità"]], args["Nazionalità"] or "")if args.Cittadinanza thenself:_addText(" con cittadinanza ")self:_addWlink(link_nazionalita[args.Cittadinanza], args.Cittadinanza)endif args["NazionalitàNaturalizzato"] thenself:_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"])endif args["PostNazionalità"] thenif self:_needSpace(args["PostNazionalità"]) thenself:_addText(" ")endself:_addText(args["PostNazionalità"])endend-- =============================================================================--                            Funzioni esportate-- =============================================================================local p = {}-- Funzione per {{#invoke:Bio|categorie}} utilizzato da Modulo:Bio/testfunction 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)endreturn p

Menu di navigazione