Modulo Lua che implementa le funzionalità delTemplate:Bio.
Ha le seguenti sottopagine di configurazione:
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")localmString=require("Modulo:String")localmWikidata=require("Modulo:Wikidata")localcfg=mw.loadData("Modulo:Bio/Configurazione")localex_attivita=mw.loadData("Modulo:Bio/Ex attività")-- argomenti passati al templatelocalargs-- table per contenere gli errorilocalerrorTable={}-- nomi dei parametri per l'attività e la nazionalitàlocalattivitaParams={"Attività","Attività2","Attività3"}localnazionalitaParams={"Nazionalità","NazionalitàNaturalizzato","Cittadinanza"}-- =============================================================================-- Funzioni di utilità-- =============================================================================-- Aggiunge l'output del [[Template:Avviso]] e una categoria di warning a errorTablelocalfunctionaddAvviso(testo,category)localtexttext=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)ifmw.title.getCurrentTitle().namespace==0thentable.insert(errorTable,string.format("[[Categoria:%s]]\n",cfg.categorie[category]))endend-- Wrapper di mw.title.exists, verifica sia che name sia valido, sia che esistalocalfunctiontitleExists(name)localtitle=mw.title.new(name)returntitleandtitle.existsendlocalfunctioncurrentTitleEquals(name)localtitle=mw.title.getCurrentTitle().texttitle=mw.text.split(title," %(")[1]returntitle==nameormw.getContentLanguage():lcfirst(title)==nameend-- Se date inizia con "1 " o "1°" restituisce una nuova data che inizia per "1º", altrimenti datelocalfunctionfixFirstOfMonth(date)date=date:gsub("^1%s","1º ")date=date:gsub("^1\194\176","1º")returndateend-- Restituisce "ed" se nextWord inizia con "e", altrimenti "e"localfunctiongetEufonica(nextWord)returnnextWord: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 falselocalfunctionargsSearch(params,values)localret=falsefor_,paraminipairs(params)dofor_,valueinipairs(values)doifargs[param]==valuethenreturntrueendendendreturnfalseend-- Riconosce le ex attività previste e le restituisce senza "ex"localfunctionisExAttivita(attivita)localretattivita=attivita:match("^ex (.+)$")ifattivitathenfor_,vinipairs(ex_attivita)doifv==attivitathenret=attivitabreakendendendreturnretend-- =============================================================================-- classe ArgsParser-- =============================================================================localArgsParser={}functionArgsParser:new()localself={}setmetatable(self,{__index=ArgsParser})returnselfend-- Parsifica i parametri passati al modulo e aggiunge eventuali categorie di errore.-- Restituisce i parametri conosciuti scartando quelli valorizzati a stringa vuota.functionArgsParser:parse(origArgs)localparamcfg=require("Modulo:Bio/Parametri")localretArgs={}-- controlla i parametri conosciuti e li copiafork,vinpairs(origArgs)doifparamcfg.params[k]thenifv~=""thenretArgs[k]=vendelseaddAvviso(cfg.warningParams.testo:gsub("$1","il parametro '"..(tonumber(k)and(v==""and" "orv)ork).."' è sconosciuto"),"unknown-params")endend-- controlla il valorefori,validatorinpairs(paramcfg.validators)doifretArgs[validator.param]thenifnotself:_checkParamValue(retArgs[validator.param],validator.valuetest,retArgs)thenifvalidator.errmsgthenaddAvviso(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)locallang=mw.getContentLanguage()for_,paraminipairs(attivitaParams)doifretArgs[param]andnotcfg.attivita_maiuscolo[retArgs[param]]thenretArgs[param]=lang:lcfirst(retArgs[param])endendfor_,paraminipairs(nazionalitaParams)doretArgs[param]=retArgs[param]andlang:lcfirst(retArgs[param])endreturnretArgsend-- Utilizzata da parse per controllare il valore di un parametro.-- Restituisce true se il valore è valido altrimenti false.functionArgsParser:_checkParamValue(value,valueTest,otherArgs)localret=trueiftype(valueTest)=="function"thenret=valueTest(value,otherArgs)elseiftype(valueTest)=="string"andnotvalue:match(valueTest)thenret=falseendreturnretend-- =============================================================================-- classe CategoryManager-- =============================================================================localCategoryManager={}functionCategoryManager:new()localself={}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()localtitle=mw.title.getCurrentTitle()iftitle.namespace==0andtitle.text~='Pagina principale'orargs.Debugthen-- imposta la magic word defaultsortlocalsortkeyifargs.ForzaOrdinamentothensortkey=args.ForzaOrdinamento:gsub("(.-)%s*,%s*(.*)","%1 ,%2")elseifargs.Soprannomeandargs.CognomeandcurrentTitleEquals(args.Soprannome.." "..args.Cognome)thensortkey=mString.collate({args={args.Cognome.." ,"..args.Soprannome}})elseifargs.PseudonimoandcurrentTitleEquals(args.Pseudonimo)thenlocalpseudonimo=mString.collate({args={args.Pseudonimo}})ifpseudonimo~=args.Pseudonimothensortkey=pseudonimoendelseifargs.Cognomeandargs.Nomethensortkey=mString.collate({args={args.Cognome.." ,"..args.Nome}})elseifargs.Nomethenlocalnome=mString.collate({args={args.Nome}})ifnome~=args.Nomethensortkey=nomeendendifsortkeythenifargs.Debugthen-- 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 > 122localyears={birth=tonumber(args.AnnoNascita),death=notargs.AnnoMorteandos.date("%Y")ortonumber(args.AnnoMorte)}ifyears.birthandyears.deathandyears.death-years.birth>122thenself:_addCategory(cfg.categorie["controllo-età"])end-- eventuali categorie di servizio per Wikidataifnotargs.Debugthenself:_addCategoriesWikidata()endendreturnselfendfunctionCategoryManager:getCategories()returnself.categoriesendfunctionCategoryManager:_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.functionCategoryManager:_addCategoryWikidata(propertyId,cat)ifnotmWikidata._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}}.functionCategoryManager:_addCategoriesWikidata()-- Per Speciale:LinkPermanente/80165551#Proposta_categoria_di_servizio_biografie_con_data_di_morte_su_Wikidataifnotargs.AnnoMorteandmWikidata._getProperty({"P570"})thenself:_addCategory("Voci con template Bio senza AnnoMorte ma con data di morte su Wikidata")endifmWikidata._instanceOf({"Q5"})then-- Per Speciale:LinkPermanente/66620402#Add_this_text_to_Template:Bioifargs["Nazionalità"]thenself:_addCategoryWikidata("P27","Voci con template Bio e nazionalità assente su Wikidata")end-- Per Speciale:LinkPermanente/80165551#Wikidata_d:Property:P21ifnotargs.Sessoorargs.Sesso=="M"thenself:_addCategoryWikidata("P21","Voci con template Bio e sesso (M) assente su Wikidata")elseifargs.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_P570ifargs.LuogoNascitaandnotargs.LuogoNascitaLinkthenself:_addCategoryWikidata("P19","Voci con template Bio e LuogoNascita assente su Wikidata")endifargs.LuogoNascitaLinkthenself:_addCategoryWikidata("P19","Voci con template Bio e LuogoNascitaLink assente su Wikidata")endifargs.LuogoMorteandnotargs.LuogoMorteLinkthenself:_addCategoryWikidata("P20","Voci con template Bio e LuogoMorte assente su Wikidata")endifargs.LuogoMorteLinkthenself:_addCategoryWikidata("P20","Voci con template Bio e LuogoMorteLink assente su Wikidata")endifargs.AnnoNascitathenself:_addCategoryWikidata("P569","Voci con template Bio e AnnoNascita assente su Wikidata")endifargs.AnnoMorteandargs.AnnoMorte~="?"thenself:_addCategoryWikidata("P570","Voci con template Bio e AnnoMorte assente su Wikidata")endifargs.ImmagineandnottitleExists("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)localannoNascita=tonumber(args.AnnoNascita)localannoMorte=tonumber(args.AnnoNascita)if(args["Nazionalità"]=="italiano"orargs["Nazionalità"]=="italiana")and((annoNascitaor0)>1861or(annoMorteor0)>1861)then-- Le cittadinanze "Italia" e "Regno d'Italia" non si escludono, quindi non va usato "elseif"localcittadRegno=falselocalcittadRepubblica=falseif((annoNascita~=nilandannoNascita<1946)or(annoMorte~=nilandannoMorte<1946))thenself:_addCategoryWikidata("P27","Voci con template Bio e cittadinanza Regno d'Italia assente su Wikidata")cittadRegno=trueendif((annoNascitaor0)>1946or(annoMorteor0)>1946)thenself:_addCategoryWikidata("P27","Voci con template Bio e cittadinanza Italia assente su Wikidata")cittadRepubblica=trueendifnot(cittadRegnoorcittadRepubblica)thenself:_addCategoryWikidata("P27","Voci con template Bio e Nazionalità italiana assente su Wikidata")endelseifargs["Nazionalità"]=="statunitense"and((annoNascitaor0)>1776or(annoMorteor0)>1776)thenself:_addCategoryWikidata("P27","Voci con template Bio e Nazionalità statunitense assente su Wikidata")elseifargs["Nazionalità"]=="francese"and((annoNascitaor0)>1799or(annoMorteor0)>1799)thenself:_addCategoryWikidata("P27","Voci con template Bio e Nazionalità francese assente su Wikidata")end-- Per Speciale:LinkPermanente/80431600#Wikidata_properties_P106ifargsSearch(attivitaParams,{"calciatore","ex calciatore","calciatrice"})thenself:_addCategoryWikidata("P106","Voci con template Bio e Attività assente su Wikidata (calciatore)")endifargsSearch(attivitaParams,{"attore","attrice"})thenself:_addCategoryWikidata("P106","Voci con template Bio e Attività assente su Wikidata (attore)")endifargsSearch(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)functionCategoryManager:_getPluralAttivita(attivita)localpluralself.plurale_attivita=self.plurale_attivitaormw.loadData("Modulo:Bio/Plurale attività")plural=self.plurale_attivita[isExAttivita(attivita)orattivita]ifnotpluralthenaddAvviso(cfg.warningA.testo..cfg.warningA.testo2a:gsub("$1",attivita)..cfg.warningA.testo3,"warning")endreturnpluralend-- Restituisce il plurale della nazionalità o nil se non trovato (con eventuale warning)functionCategoryManager:_getPluralNazionalita(nazionalita)localpluralself.plurale_nazionalita=self.plurale_nazionalitaormw.loadData("Modulo:Bio/Plurale nazionalità")plural=self.plurale_nazionalita[nazionalita]ifnotpluralthenaddAvviso(cfg.warningN.testo..cfg.warningN.testo2a:gsub("$1",nazionalita)..cfg.warningN.testo3,"warning")endreturnpluralend-- Restituisce il plurale dei parametri necessari per le categoriefunctionCategoryManager:_getPluralsAttivitaNazionalita()localplurals={}localattnaznecessarie=not(args.Categorie=="no"andargs.FineIncipit)-- Nazionalità può essere vuota solo quando c'è Categorie=no e FineIncipitifnotargs["Nazionalità"]andattnaznecessariethenaddAvviso(cfg.warningN.testo..cfg.warningN.testo2b..cfg.warningN.testo3,"warning")endfor_,nazionalitainipairs(nazionalitaParams)doifargs[nazionalita]thenplurals[nazionalita]=self:_getPluralNazionalita(args[nazionalita])endend-- Attività può essere vuota solo quando c'è Categorie=no e FineIncipitifnotargs["Attività"]andattnaznecessariethenaddAvviso(cfg.warningA.testo..cfg.warningA.testo2b..cfg.warningA.testo3,"warning")endfor_,attivitainipairs(attivitaParams)doifargs[attivita]thenplurals[attivita]=self:_getPluralAttivita(args[attivita])endendreturnpluralsend-- Calcola il valore di Epoca se non inserito dall'utente.functionCategoryManager:_getEpoca()localretlocalannoNascita=tonumber(args.AnnoNascita)localannoMorte=tonumber(args.AnnoMorte)ifnotannoNascitathenannoNascita=args.AnnoNascita:match('^(%d+) a%.C%.$')annoNascita=annoNascitaandtonumber(annoNascita)*-1endifannoNascitaandannoNascita>=2000thenreturn"2000"endifnotannoMorteandargs.AnnoMortethenannoMorte=args.AnnoMorte:match('^(%d+) a%.C%.$')annoMorte=annoMorteandtonumber(annoMorte)*-1endifannoNascitaandannoMorteandannoNascita>=-500andannoNascita<=2100andannoMorte>=-500andannoMorte<=2100and((annoNascita>=0andannoMorte>=0)or(annoNascita<0andannoMorte<0))thenlocalsign=''ifannoNascita<0thenannoNascita,annoMorte=-annoNascita,-annoMortesign='-'endlocalsecoloNascita=math.floor((annoNascita-1)/100)*100localsecoloMorte=math.floor((annoMorte-1)/100)*100ret=secoloNascita==secoloMorteand(sign..secoloNascita)ornilendreturnretend-- Aggiunge Categoria:X dei secoli, se esistonofunctionCategoryManager:_addCatSecolo(catname,epoca1,epoca2)localok=falsefor_,epocainipairs({epoca1,epoca2})doifepocaandtitleExists("Categoria:"..catname.." "..epoca)thenself:_addCategory(catname.." "..epoca)ok=trueendendreturnokend-- Aggiunge le categorie: Attività nazionalità [del XYZ secolo]functionCategoryManager:_addAttivita(plurals)localcatname,epoca1,epoca2,added,addatt,addnaz,add1,nazmonosec,addmonosecaddatt={}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 automaticamenteifnotargs.Epocaandnotargs.Epoca2andargs.AnnoNascitathenepoca1=self:_getEpoca()epoca1=epoca1andcfg.epoche[epoca1]elseepoca1=args.Epocaandcfg.epoche[args.Epoca]epoca2=args.Epoca2andcfg.epoche[args.Epoca2]endifnotepoca1andnotepoca2thenself:_addCategory(cfg.categorie["no-epoca"])endifargs.Categorie~="no"thenfor_,attivitainipairs(attivitaParams)doifplurals[attivita]thenfor_,nazionalitainipairs(nazionalitaParams)doifplurals[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"ifaddedthenadd1=trueaddatt[attivita]=trueaddnaz[nazionalita]=trueelseself:_addCategory(catname)for_,vinipairs(nazmonosec)do-- pezza per naz. monosecoloifplurals[nazionalita]==vthenaddmonosec=trueendendendendendendendend-- in mancanza di "A N del S" prova "A del S" e "N del S"for_,attivitainipairs(attivitaParams)doifplurals[attivita]andnotaddatt[attivita]thenadd1=self:_addCatSecolo(plurals[attivita],epoca1,epoca2)oradd1endendfor_,nazionalitainipairs(nazionalitaParams)doifplurals[nazionalita]andnotaddnaz[nazionalita]thenadd1=self:_addCatSecolo(plurals[nazionalita],epoca1,epoca2)oradd1for_,vinipairs(nazmonosec)do-- pezza per naz. monosecoloifplurals[nazionalita]==vandnotadd1andnotaddmonosecthenself:_addCategory(plurals[nazionalita])add1=trueendendendendifnotadd1andnotaddmonosecthenself:_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 nilfunctionCategoryManager:_getCatLuoghi(titleLink,title,catPrefix)localcatself.catLuoghi=self.catLuoghiormw.loadData("Modulo:Bio/Cat luoghi")iftitleLinkandtitlethencat=self.catLuoghi[titleLink]elseiftitlethencat=self.catLuoghi[title]endreturncatand(catPrefix.." "..cat)ornilend-- Aggiunge le categorie: Nati/Morti nell'anno/giorno/luogofunctionCategoryManager:_addNatiMorti()localcat1,cat2ifargs.AnnoNascitathencat1="Nati nel "..args.AnnoNascitacat2="Nati nell'"..args.AnnoNascitaiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endendifargs.AnnoMortethenifargs.AnnoMorte=="?"thenself:_addCategory(cfg.categorie["annomorte-punto-interrogativo"])elsecat1="Morti nel "..args.AnnoMortecat2="Morti nell'"..args.AnnoMorteiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endendelseself:_addCategory(cfg.categorie["annomorte-assente"])endifargs.GiornoMeseNascitathencat1="Nati il "..fixFirstOfMonth(args.GiornoMeseNascita)cat2="Nati l'"..args.GiornoMeseNascitaiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endendifargs.GiornoMeseMortethencat1="Morti il "..fixFirstOfMonth(args.GiornoMeseMorte)cat2="Morti l'"..args.GiornoMeseMorteiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endend-- prima di verificare le categorie per LuogoNascitaLink e LuogoNascita-- viene controllata una lista di eccezionicat1=self:_getCatLuoghi(args.LuogoNascitaLink,args.LuogoNascita,"Nati")ifcat1thenself:_addCategory(cat1)elseifargs.LuogoNascitaLinkthencat1="Nati a "..args.LuogoNascitaLinkcat2="Nati ad "..args.LuogoNascitaLinkiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endelseifargs.LuogoNascitathencat1="Nati a "..args.LuogoNascitacat2="Nati ad "..args.LuogoNascitaiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("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")ifcat1thenself:_addCategory(cat1)elseifargs.LuogoMorteLinkthencat1="Morti a "..args.LuogoMorteLinkcat2="Morti ad "..args.LuogoMorteLinkiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endelseifargs.LuogoMortethencat1="Morti a "..args.LuogoMortecat2="Morti ad "..args.LuogoMorteiftitleExists("Categoria:"..cat1)thenself:_addCategory(cat1)elseiftitleExists("Categoria:"..cat2)thenself:_addCategory(cat2)endendend-- =============================================================================-- classe Incipit-- =============================================================================localIncipit={}functionIncipit:new()localself={}setmetatable(self,{__index=Incipit})self.textTable={}self:_addImmagine()self:_addNomeCognome()self:_addNascitaMorte()ifargs.Soprannomeorargs.Pseudonimoorargs.PostCognomeVirgolathenself:_addText(",")endifargs.FineIncipitthenifself:_needSpace(args.FineIncipit)thenself:_addText(' ')endself:_addText(args.FineIncipit)elseself:_addAttivita()endifargs.Punto~="no"thenself:_addText((args.FineIncipit=="e"orargs.FineIncipit=="ed"orargs.FineIncipit==",")and" "or".")endreturnselfendfunctionIncipit:getIncipit()returntable.concat(self.textTable)end-- Aggiunge testo alla risposta, svolge anche la funzione di concatenatorefunctionIncipit:_addText(...)localarg={...}for_,valinipairs(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.functionIncipit:_addWlink(target,label,labelPrefix)iftargetandlabelandlabelPrefixthenlocalcountlabel,count=label:gsub("^"..labelPrefix.." ","")ifcount==1thenself:_addText(labelPrefix," ")endendiftargetandlabelthenself:_addText("[[",target,"|",label,"]]")elseself:_addText("[[",targetorlabel,"]]")endend-- Aggiunge una immagine alla risposta, size e caption sono opzionalifunctionIncipit:_addImage(name,size,caption)self:_addText("[[File:",name,"|thumb")ifsizethenself:_addText("|",size,"px")endifcaptionthenself:_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)functionIncipit:_needSpace(text)returnmw.ustring.match(mw.ustring.sub(text,1,1),"%w")~=nilortext:sub(1,2)=="[["ortext:sub(1,1)=="("ortext:sub(1,1)=="'"ormw.ustring.sub(text,1,1)=="–"ortext:sub(1,5)=="<span"endfunctionIncipit:_getArticleMan(attivita)localarticleifcfg.articoli_maschili["uno"][attivita]thenarticle="uno"elseifcfg.articoli_maschili["una"][attivita]thenarticle="una"elsearticle="un"endreturnarticleendfunctionIncipit:_getArticleWoman(attivita)localarticle-- aggiunge anche uno spazio nel caso non usi l'apostrofoifcfg.articoli_femminili["un"][attivita]thenarticle="un "elseifattivitaandattivita:match("^[aeiou]")thenarticle="un'"elsearticle="una "endreturnarticleendfunctionIncipit:_addImmagine()localcaptionifargs.Immaginethenifargs.Didascaliathencaption=args.Didascaliaelseifargs.PseudonimoandcurrentTitleEquals(args.Pseudonimo)thencaption=args.Pseudonimoelseifargs.Soprannomeandargs.CognomeandcurrentTitleEquals(args.Soprannome.." "..args.Cognome)thencaption=args.Soprannome.." "..args.Cognomeelseifargs.SoprannomeandcurrentTitleEquals(args.Soprannome)thencaption=args.Soprannomeelseifargs.CognomePrimaandargs.Nomeandargs.Cognomethencaption=args.Cognome.." "..args.Nomeelseifargs.Nomethencaption=args.Nomeendifargs.Cognomethencaption=(captionor"").." "..args.Cognomeendendendifargs.Didascalia2thencaption=(captionor"").."<hr />"..args.Didascalia2endself:_addImage(args.Immagine,args.DimImmagine,caption)elseifargs.Didascalia2then-- parentesi () extra per non restituire anche il gsub.countself:_addText((cfg.didascalia2:gsub("$1",args.Didascalia2)))endendfunctionIncipit:_addNomeCognome()ifargs.Titolothenself:_addText(args.Titolo," ")endifargs.PseudonimoandcurrentTitleEquals(args.Pseudonimo)thenself:_addText("'''",args.Pseudonimo,"'''")ifargs.PostPseudonimothenifself:_needSpace(args.PostPseudonimo)thenself:_addText(" ")endself:_addText(args.PostPseudonimo)endself:_addText(", pseudonimo di ")end-- inizio grassettoself:_addText("'''")ifargs.CognomePrimaandargs.Nomeandargs.Cognomethenself:_addText(args.Cognome," ",args.Nome,mw.getCurrentFrame():expandTemplate{title="Nota nome",args={[1]=args.CognomePrima,[2]=args.Cognome}})elselocalno_spaceifargs.Nomethenself:_addText(args.Nome)-- niente spazio prima di Cognome se Nome termina con «d'»no_space=mw.ustring.match(args.Nome," d'$")and''endifargs.Cognomethenself:_addText(no_spaceor" ",args.Cognome)endend-- fine grassettoself:_addText("'''")ifargs.PostCognomeVirgolathenself:_addText(", ",args.PostCognomeVirgola)elseifargs.PostCognomethenifself:_needSpace(args.PostCognome)thenself:_addText(" ")endself:_addText(args.PostCognome)endifargs.Soprannomethenself:_addText(", ",(notargs.Sessoorargs.Sesso=="M")and"detto"or"detta"," ","'''",args.Soprannome,"'''")ifargs.PostSoprannomethenifself:_needSpace(args.PostSoprannome)thenself:_addText(" ")endself:_addText(args.PostSoprannome)endendifargs.PseudonimoandnotcurrentTitleEquals(args.Pseudonimo)thenself:_addText(", ",(notargs.Sessoorargs.Sesso=="M")and"noto"or"nota"," anche con lo pseudonimo di ","'''",args.Pseudonimo,"'''")ifargs.PostPseudonimothenifself:_needSpace(args.PostPseudonimo)thenself:_addText(" ")endself:_addText(args.PostPseudonimo)endendendfunctionIncipit:_addNascitaMorte()-- si apre la parentesiself:_addText(" (")ifargs.PreDatathenself:_addText(args.PreData,"; ")endlocaldatimancanti=not(args.LuogoNascitaorargs.GiornoMeseNascitaorargs.AnnoNascitaorargs.NoteNascitaorargs.LuogoMorteorargs.GiornoMeseMorte)localfloruit=args.AnnoMorte=="?"and(args.Floruitorcfg.epoche[args.Epoca])ifargs.LuogoNascitathenself:_addWlink(args.LuogoNascitaLink,args.LuogoNascita)ifargs.LuogoNascitaAltthenifself:_needSpace(args.LuogoNascitaAlt)thenself:_addText(" ")endself:_addText(args.LuogoNascitaAlt)endself:_addText(", ")endifargs.GiornoMeseNascitatheniftitleExists(args.GiornoMeseNascita)thenself:_addWlink(args.GiornoMeseNascita)elseself:_addText(args.GiornoMeseNascita)endself:_addText(" ")endifargs.AnnoNascitatheniftitleExists(args.AnnoNascita)thenself:_addWlink(args.AnnoNascita)elseself:_addText(args.AnnoNascita)endelseifnotfloruitornotdatimancantithenself:_addText("...")endifargs.NoteNascitathenifself:_needSpace(args.NoteNascita)thenself:_addText(" ")endself:_addText(args.NoteNascita)endifargs.AnnoMorteand(notfloruitornotdatimancanti)thenself:_addText(" – ")ifargs.LuogoMortethenself:_addWlink(args.LuogoMorteLink,args.LuogoMorte)ifargs.LuogoMorteAltthenifself:_needSpace(args.LuogoMorteAlt)thenself:_addText(" ")endself:_addText(args.LuogoMorteAlt)endself:_addText(", ")endifargs.GiornoMeseMortetheniftitleExists(args.GiornoMeseMorte)thenself:_addWlink(args.GiornoMeseMorte)elseself:_addText(args.GiornoMeseMorte)endself:_addText(" ")endifargs.AnnoMortethenifargs.AnnoMorte=="?"thenself:_addText("...")elseiftitleExists(args.AnnoMorte)thenself:_addWlink(args.AnnoMorte)elseself:_addText(args.AnnoMorte)endendendend-- se date ignote, usa Floruit o lo ricava da Epocaifnotargs.AnnoNascitaandargs.AnnoMorte=="?"thenlocalfl=args.Floruitifnotflandcfg.epoche[args.Epoca]thenfl=mw.ustring.gsub(cfg.epoche[args.Epoca],"^del ?l?'?","")-- se due epoche, le mette entrambe senza ripetere la parola "secolo"ifcfg.epoche[args.Epoca2]theniffl~="I secolo a.C."thenfl=fl.."|"..mw.ustring.gsub(fl," secolo.*$","")endfl="[["..fl.."]]-[["..mw.ustring.gsub(cfg.epoche[args.Epoca2],"^del ?l?'?","").."]]"endendiffltheniftitleExists(fl)thenfl="[["..fl.."]]"endifnotdatimancantithenself:_addText("; ")endself:_addText("[[floruit|fl.]] ",fl)endendifargs.NoteMortethenifself:_needSpace(args.NoteMorte)thenself:_addText(" ")endself:_addText(args.NoteMorte)end-- si chiude la parentesiself:_addText(")")endfunctionIncipit:_addAttivita()locallink_attivita=mw.loadData("Modulo:Bio/Link attività")locallink_nazionalita=mw.loadData("Modulo:Bio/Link nazionalità")self:_addText(" ")ifargs["PreAttività"]thenself:_addText(args["PreAttività"]," ")elseself:_addText("è ")ifargs.AnnoMortethenself:_addText((notargs.Sessoorargs.Sesso=="M")and"stato "or"stata ")endifnotargs.Sessoorargs.Sesso=="M"thenself:_addText(self:_getArticleMan(args["Attività"])," ")elseself:_addText(self:_getArticleWoman(args["Attività"]))endendlocalgetLinkAttivita=function(attivita)ifnotattivitathenreturnendlocalex_attivita=isExAttivita(attivita)returnlink_attivita[ex_attivitaorattivita]orex_attivitaendself:_addWlink(getLinkAttivita(args["Attività"]),args["Attività"]or"","ex")ifargs["Attività2"]thenifargs["Attività3"]orargs["AttivitàAltre"]thenself:_addText(",")elseself:_addText(" ",getEufonica(args["Attività2"]))endself:_addText(" ")self:_addWlink(getLinkAttivita(args["Attività2"]),args["Attività2"],"ex")endifargs["Attività3"]thenifargs["AttivitàAltre"]thenself:_addText(",")elseself:_addText(" ",getEufonica(args["Attività3"]))endself:_addText(" ")self:_addWlink(getLinkAttivita(args["Attività3"]),args["Attività3"],"ex")endifargs["AttivitàAltre"]thenifself:_needSpace(args["AttivitàAltre"])thenself:_addText(" ")endself:_addText(args["AttivitàAltre"])endself:_addText(" ")self:_addWlink(link_nazionalita[args["Nazionalità"]],args["Nazionalità"]or"")ifargs.Cittadinanzathenself:_addText(" con cittadinanza ")self:_addWlink(link_nazionalita[args.Cittadinanza],args.Cittadinanza)endifargs["NazionalitàNaturalizzato"]thenself:_addText(" ")self:_addWlink("Naturalizzazione",(notargs.Sessoorargs.Sesso=="M"or(args.Sesso=="F"andself:_getArticleWoman(args["Attività"])=="un "))and"naturalizzato"or"naturalizzata")self:_addText(" ")self:_addWlink(link_nazionalita[args["NazionalitàNaturalizzato"]],args["NazionalitàNaturalizzato"])endifargs["PostNazionalità"]thenifself:_needSpace(args["PostNazionalità"])thenself:_addText(" ")endself:_addText(args["PostNazionalità"])endend-- =============================================================================-- Funzioni esportate-- =============================================================================localp={}-- Funzione per {{#invoke:Bio|categorie}} utilizzato da Modulo:Bio/testfunctionp.categorie(frame)args=ArgsParser:new():parse(frame.args)localcategories=CategoryManager:new():getCategories()returntable.concat(errorTable)..(args.Debugand(table.concat(categories,'<br />'):gsub('%[%[','[[:'))..'<br />'ortable.concat(categories))end-- Funzione per il template per {{Bio}}functionp.main(frame)-- gli errori generano avvisi, ma non interrompono l'esecuzione,-- come avveniva nel vecchio template.args=ArgsParser:new():parse(frame:getParent().args)localcatTable=CategoryManager:new():getCategories()returntable.concat(errorTable)..Incipit:new():getIncipit()..table.concat(catTable)endreturnp