Vai al contenuto

Modulo:Citazione

Da Wikiversità, l'apprendimento libero.

Modulo Lua per la riproduzione delle funzioni dei vari template {{Cita libro}}, {{Cita web}}, {{Cita news}}, {{Cita pubblicazione}}, {{Cita conferenza}} e {{Cita video}}.

Quelle che seguono sono note tecniche sul funzionamento del modulo. Per le istruzioni su come usarlo per inserire citazioni nelle voci vedi il manuale di{{Cita testo}}.

Sottomoduli

  • Modulo:Citazione/Configurazione- Contiene le tabelle di configurazione con i nomi dei parametri, i messaggi di errore, i caratteri di separazione...
  • Modulo:Citazione/Whitelist- Contiene le tabelle dei parametri accettati dal modulo per poter identificare parametri con un nome errato.
  • Modulo:Citazione/Suggerimenti- Contiene una tabella in cui è possile inserire nomi di parametri che vengono sbagliati spesso e suggerire nel messaggio d'errore il nome del parametro corretto.
  • Modulo:Citazione/Argomenti- Serve a generare Modulo:Citazione/Whitelist ed è usato una tantum.

Funzioni accessorie

Nel seguito per settata si intende una variabile diversa da nil e da stringa nulla

is_set(var)
vera se una variabile è settata
first_set(...)
ritorna la prima variabile settata
inArray( needle, haystack )
scandisce l'arrayhaystacke ritorna la posizione in cui si trova il valoreneedle.Seneedlenon si trova inhaystacko ènilritornafalse
substitute( msg, args )
ritorna la stringamsgcompilata usando la tabella di valoriargs.Basata sulla funzionemw.message.newRawMessage,non granchè documentata, apparentemente nella stringa i$nvengono sostituiti dal valore in posizione ennesima inargs.Seargsè nil ritorna nil
wrap( key, str, lower )
formatta il messaggiokeycon la stringastr.keydeve essere un indice della tabellacitation_config.messages.Selowerè vero il messaggio viene messo in minuscolo prima di inserirestr
debug_msg(msg)
inserisce un messaggio di debug nella coda dei messaggi di errore per essere emesso a video
debug_value(name, value)
inserisce il messaggio di debugname=value.Usata per emettere il valore di una variabile, da usare per esempio come debug_value('name', name)
argument_wrapper( args )
restituisce una tabella per accedere ai valori della tabella originaleargsmediante una tabella di alias. Data l'istruzioneA=argument_wrapper(args)la chiamataA[key]il valoreargs[first_set(citation_config.aliases[key])].Questo permette la localizzazione dei parametri e la creazione di alias per lo stesso valore. Per esempio secitation_config.aliases['Chapter'] = {'capitolo', 'contributo', 'voce', 'articolo', 'sezione' }la chiamataA['Chapter']resituirà uno dei valori settati traargs['capitolo'],args['contributo'],args['voce'],args['articolo'],args['sezione'].Aggiunge inoltre il metodo A:ORIGIN che restituisce l'alias con il quale è stato trovato un valore. I valori trovati vengono bufferizzati in una tabella interna.
Aggiunge un messaggio alla coda di errori se:
  • keynon è presente incitation_config.aliases
  • keyè una tabella di valori e più di uno di questi è settato
  • se inargsnon viene trovato alcun valore corrispondente a uno degli alias dikeyritorna stringa vuota ""
validate(name)
ritornatruesenamenon è nil ed è il nome di un parametro accettato,falsein caso contrario
errorcomment( content, hidden )
formatta il commentocommentper la visualizzazione, sehiddenètrueil codice sarà inserito ma non visibile salvo analizzare il codice html della pagina, altrimenti sarà formattato come da settaggio delle classi "error" e "citation-comment" nel css (normalmente una scritta in rosso)
seterror( error_id, arguments, raw, prefix, suffix )
formatta il commento con codiceerror_idcon la tabella di argomentiarguments.Se valorizzatiprefixesuffixvengono aggiunti rispettivamente prima e dopo il messggio. Serawètrueil messaggio viene ritornato senza essere passato prima pererrorcomment.
la chiaveerror_idfa riferimento alla tabella di messaggicitation_config.error_conditionsche per ogni codice di errore restituisce il messaggio da formattare, la categoria di errore in cui inserire la voce e se il messaggio deve essere visibile o nascosto.

Fragment

Per gestire l'unione dei pezzi di citazione, viene definito un "oggetto" Lua (in realtà una tabella con una metatable che definisce alcuni metodi aggiuntivi). Unfragmentè composto da un array il cui primo elemento è un stringa da inserire all'inizio della sequenza, seguito da uno o più stringhe e terminati da una stringa da inserire al termine della sequenza. Quando due frammentif1ef2vengono uniti (vedifragment.appendefragment.appends) viene valutata la priorità dell'ultimo separatore dif1e quella del primo dif2e conservato solo quello con priorità maggiore. Il nuovo frammento avrà il separatore iniziale dif1e quello finale dif2.

Fragment.new(text, sep_key)
crea un pseudooggetto Lua che memorizza l'array di stringhetextusando come separatore tra una stringa e l'altrasep_key.Setta come separatore iniziale per la sequenza la stringa nulla e come separatore finalesep_key.Ritorna l'oggetto creato.
Sep_keydeve essere una chiave della tabellaFragment.priorityche per ogni separatore indica la sua priorità (quindi quale separatore prevale quando due frammenti vengono uniti) e cosa inserire esattamente (per esempio per "," inserisce in realtà "," — aggiunge cioè lo spazio). La tabella è caricata dal modulo di configurazione, un esempio è:
[ "" ] = { order=0, sep = "" },
[ "" ] = { order=1, sep = "" },
[ "," ] = { order=2, sep = "," },
[ "." ] = { order=3, sep = "." },
[ "in" ] = {order=4, sep = "in" },
[ "" ] = { order=5, sep = "" },spazio semplice che però prevale su altri separatori
[ "nothing" ] = {order=6, sep= "" }stringa nulla che prevale su tutto (per forzare nessun separatore a inizio citazione)
Fragment:start(sep_key)
setta come separatore inizialesep_key
Fragment:last(sep_key)
setta come separatore finalesep_key
Fragment:empy(sep_key)
ritornatruese fragment è un frammento vuoto (contiene un array di stringhe vuoto)
Fragment:append(txr)
appende il frammento o strignatxrin fondo afragment(nel caso chetxrè una stringa la trasforma infragmentconsep_keyuguale a quella del frammento a cui viene appesa)
Fragment:appends(txr)
appende un array misto di frammenti/stringhe

-- Modulo per la gestione delle citazioni, originariamente importato dalla
-- revisione 555909894 del 20/5/2013 da [[:en:Module:Citation/CS1]]

--[[ ===============================================================================
Variabile in cui vengono memorizzate le condizioni di errore registrate durante l'esecusione
delle funzioni del modulo.
===============================================================================]]
localz={
error_categories={};-- lista delle categorie di errore
error_ids={};-- lista dei codici di errore
message_tail={};-- messagi di errore da visualizzare in coda alla citazione
}

--[[ ===============================================================================
Caricamente delle tabelle di configurazione del modulo.
===============================================================================]]
localcfg=mw.loadData('Modulo:Citazione/Configurazione');

--[[ ===============================================================================
Lista di tutti i parametri riconosciuti.
===============================================================================]]
localwhitelist=mw.loadData('Modulo:Citazione/Whitelist');

--[[ ===============================================================================
Ritorna true se una variabile è settata (diversa da nil e da stringa vuota)
===============================================================================]]
localfunctionis_set(var)
returnnot(var==nilorvar=='');
end

--[[ ===============================================================================
Ritorna la prima variabile settata di quelle passate alla funzione
===============================================================================]]
localfunctionfirst_set(...)
locallist={...};
for_,varinpairs(list)do
ifis_set(var)then
returnvar;
end
end
end

--[[ ===============================================================================
Ritorna la posizione di needle nella lista haystack, altrimenti ritorna false
===============================================================================]]
localfunctionin_array(needle,haystack)
ifneedle==nilthenreturnfalse;end
forn,vinipairs(haystack)do
ifv==needlethenreturnn;end
end
returnfalse;
end

--[[ ===============================================================================
Popola gli argomenti numerati nella stringa msg usando la tabella di argomenti args
===============================================================================]]
localfunctionsubstitute(msg,args)
returnargsandmw.message.newRawMessage(msg,args):plain()ormsg;
end

--[[ ===============================================================================
Rende la stringa sicura per il markup corsivo ''... ''
Nota: non si può usare <i> per il corisvo poichè il comportamento atteso se lo si
specifica per i titoli è di renderli non corsivi. Inoltre <i> e '' interagiscono
male con la funzione HTML tidy di Mediawiki
===============================================================================]]
localfunctionsafe_for_italics(str)
ifnotis_set(str)then
returnstr;
else
ifstr:sub(1,1)=="'"thenstr="<span></span>"..str;end
ifstr:sub(-1,-1)=="'"thenstr=str.."<span></span>";end

-- Remove newlines as they break italics.
returnstr:gsub('\n',' ');
end
end

--[[ ===============================================================================
Restituisce un messaggio dalla tabella cfg.messages in cui viene inserita una stringa
- key: codice del messaggio da visualizzare in cfg.messages
- str: una stringa da inserire nel messaggio, se non è definita o uguale a stringa
vuota la funzione ritorna una stringa vuota
===============================================================================]]
localfunctionwrap(key,str)
ifnotis_set(str)then
return"";
elseifin_array(key,{'italic-title','trans-italic-title'})then
str=safe_for_italics(str);
end
returnsubstitute(cfg.messages[key],{str});
end

--[[ ===============================================================================
Inserisce un messaggio di debug da visualizzare in coda alla citazione
===============================================================================]]
localfunctiondebug_msg(msg)
table.insert(z.message_tail,{set_error('debug_txt',{msg},true)});
end

--[[ ===============================================================================
A scopo di debug, aggiunge la stringa 'name=<value>' in coda alla citazione
===============================================================================]]
localfunctiondebug_value(name,value)
ifnotvaluethenvalue='nil'end
debug_msg(name..'= "'..value..' "')
end

--[[ ===============================================================================
Formatta un commento per identificare gli errori, aggiungendo la classe css per
renderlo visibile o meno
===============================================================================]]
localfunctionerror_comment(content,hidden)
returnwrap(hiddenand'hidden-error'or'visible-error',content);
end

--[[ ===============================================================================
Imposta un condizione di errore e ritorna un messaggio appropriato. L'inserimento
del messaggio nell'output è di responsabilità della funzione chiamante
-- -- error_id: codice dell'errore (una chiave valida per cfg.error_conditions)
-- -- arguments: una lista di argomenti opzionali per la formattazione del messaggio
-- -- raw: ritorna una coppia: {messaggio di errore, visibilità} invece del messaggio
-- di errore formattato
-- -- prefix: stringa da aggiungere in testa al messaggio
-- -- suffix: stringa da aggiungere in coda al messaggio
===============================================================================]]
localfunctionset_error(error_id,arguments,raw,prefix,suffix)
localerror_state=cfg.error_conditions[error_id];

prefix=prefixor"";
suffix=suffixor"";

iferror_state==nilthen
error(cfg.messages['undefined_error']);
elseifis_set(error_state.category)then
table.insert(z.error_categories,error_state.category);
end

localmessage=substitute(error_state.message,arguments);

message=mw.ustring.format('%s ([[%s#%s|%s]])',
message,cfg.messages['help page link'],error_state.anchor,
cfg.messages['help page label']
)

z.error_ids[error_id]=true;
ifin_array(error_id,{'bare_url_missing_title','trans_missing_title'})
andz.error_ids['citation_missing_title']then
return'',false;
end

message=table.concat({prefix,message,suffix});
ifraw==truethenreturnmessage,error_state.hiddenend
returnerror_comment(message,error_state.hidden);
end

--[[ ===============================================================================
Cerca il primo parametro settato da una lista di parametri e genera un errore se
più di un parametro è settato.
Ritorna la coppia (value, selected) dove value è il valore del parametro trovato e
selected il nome del parametro trovato
===============================================================================]]
localfunctionselect_one(args,possible,error_condition,index)
localvalue=nil;
localselected='';
localerror_list={};

ifindex~=nilthenindex=tostring(index);end

-- Handle special case of "#" replaced by empty string
ifindex=='1'then
for_,vinipairs(possible)do
v=v:gsub("#","");
ifis_set(args[v])then
ifvalue~=nilandselected~=vthen
table.insert(error_list,wrap('parameter',v));
else
value=args[v];
selected=v;
end
end
end
end

for_,vinipairs(possible)do
ifindex~=nilthen
v=v:gsub("#",index);
end
ifis_set(args[v])then
ifvalue~=nilandselected~=vthen
table.insert(error_list,wrap('parameter',v));
else
value=args[v];
selected=v;
end
end
end

if#error_list>0then
-- genera il messaggio di errore concatenando i parametri duplicati
localerror_str="";
if#error_list==1then
error_str=error_list[1]..cfg.messages['parameter-pair-separator'];
else
error_str=table.concat(error_list,cfg.messages['parameter-separator'])..cfg.messages['parameter-final-separator'];
end
error_str=error_str..wrap('parameter',selected);
table.insert(z.message_tail,{set_error(error_condition,{error_str},true)});
end
returnvalue,selected;
end

--[[ ===============================================================================
Funzione di supporto per la mappatura degli argomenti del file di configurazione,
così che nomi multipli possono essere assegnati ad una singola variabile interna
===============================================================================]]
localfunctionargument_wrapper(args)
localorigin={};

returnsetmetatable({
ORIGIN=function(self,k)
localdummy=self[k];--force the variable to be loaded.
returnorigin[k];
end
},
{
__index=function(tbl,k)
iforigin[k]~=nilthen
returnnil;
end

localargs,list,v=args,cfg.aliases[k];

iftype(list)=='table'then
v,origin[k]=select_one(args,list,'redundant_parameters');
iforigin[k]==nilthen
origin[k]='';-- Empty string, not nil
end
elseiflist~=nilthen
v,origin[k]=args[list],list;
else
-- maybe let through instead of raising an error?
-- v, origin[k] = args[k], k;
error(cfg.messages['unknown_argument_map']);
end

-- Empty strings, not nil;
ifv==nilthen
v=cfg.defaults[k]or'';
origin[k]='';
end

tbl=rawset(tbl,k,v);
returnv;
end,
});
end

--[[ ===============================================================================
Controlla che il nome di un parametro sia valido usando la whitelist
===============================================================================]]
localfunctionvalidate(name)
name=tostring(name);
-- Normal arguments
ifwhitelist.basic_arguments[name]thenreturntrueend
-- Arguments with numbers in them
name=name:gsub("%d+","#");
ifwhitelist.numbered_arguments[name]thenreturntrueend
-- Not found, argument not supported.
returnfalse
end

--[[ ===============================================================================
Oggetto per memorizzare gli elementi di una citazione. Un frammento di citazione è
formato dai seguenti elementi:
- self[n]: n-esimo elemento da unire, è una lista di stringhe inframezzata dai
separatori da usare per unirle.
- self.last_priority: priorità del separatore di chiusura
- self.first_priority: priorità del separatore di apertura
- self.sep_key: codice del carattere separatore di default da usare
se unita a un altro frammento
===============================================================================]]
localFragment={}

Fragment.priority={}
localFragment_mt={__index=Fragment}

Fragment.new=function(texts,sep_key)
iftype(texts)=="string"thentexts={texts}end
localfpriority=Fragment.priority
ifnotfpriority[sep_key]thensep_key=""end
localseparator=fpriority[sep_key]
localtx={}
tx.last_priority=0
tx.first_priority=0
tx.sep_key=sep_key
tx[1]=""
for_,elinipairs(texts)do
ifel~=""then
tx[#tx+1]=el
tx[#tx+1]=fpriority[tx.sep_key].sep
end
end
if#tx>1then
tx.last_priority=fpriority[tx.sep_key].order
else
tx[1]=""
end
setmetatable(tx,Fragment_mt)
returntx
end

--- cambia il separatore iniziale di un frammento di citazione
functionFragment:start(sep_key)
if#self==0thenreturnselfend
localseparator=Fragment.priority[sep_key]orFragment.priority[""]
self[1]=separator.sep
self.first_priority=separator.order
returnself
end

-- cambia il separatore finale di un frammento di citazione
functionFragment:last(sep_key)
if#self==0thenreturnselfend
localseparator=Fragment.priority[sep_key]orFragment.priority[""]
self[#self]=separator.sep
self.last_priority=separator.order
returnself
end

-- ritorna un frammento di citazione vuoto
functionFragment:empty()
return#self==0
end

-- appende una stringa o un frammento di citazione in coda
functionFragment:append(txr)
iftxr==nilthenreturnselfend
iftype(txr)=="string"thentxr=Fragment.new(txr,self.sep_key)end
if#txr==0thenreturnselfend
if#self==0thenself[1]=txr[1]end
self.last_priority=self.last_priorityor0
ifself.last_priority<txr.first_prioritythen
self[#self]=txr[1]
end
fori,elinipairs(txr)do
ifi>1thenself[#self+1]=elend
end
self.last_priority=txr.last_priority
--self.sep_key = txr.sep_key
returnself
end

-- appende una lista di stringhe o frammenti di citazione
functionFragment:appends(fragments)
for_,finipairs(fragments)do
self:append(f)
end
returnself
end

-- collassa il frammento in una stringa e la restituisce
Fragment_mt.__tostring=function(tx)
returntable.concat(tx,'')
end
-- =====================================================================
-- Fine definizione oggetto Fragment
-- =====================================================================

--[[ ===============================================================================
Formatta un link esterno a un documento
- options.code_id: codice per il link (tra prefisso e suffisso)
- options.id: etichetta del link
- options.encode: se true o nil l'url viene codificato (en:Percent-encoding)
- options.link: link alla voce wiki sul codice documento
- options.label: etichetta del link alla voce wiki sul codice documento
- option.separator: separatore tra codice e link (di default un no breaking space)
- options.prefix: prefisso dell'url
- options.suffis: suffisso dell'url (opzionale)
===============================================================================]]
localfunctionexternal_link_id(options)
localurl_string=options.code_idoroptions.id;
ifoptions.encode==trueoroptions.encode==nilthen
url_string=mw.uri.encode(url_string);
end
returnmw.ustring.format('[[%s|%s]]%s[%s%s%s %s]',
options.link,options.label,options.separatoror"",
options.prefix,url_string,options.suffixor"",
mw.text.nowiki(options.id)
);
end

--[[ ===============================================================================
Formatta un wikilink interno
- options.id: id del documento
- options.encode: se true o nil l'url viene codificato (en:Percent-encoding)
- options.link: link alla voce wiki sul codice documento
- options.label: etichetta del link alla voce wiki sul codice documento
- option.separator: separatore tra codice e link (di default un no breaking space)
- options.prefix: prefisso del link
- options.suffis: suffisso del link (opzionale)
===============================================================================]]
localfunctioninternal_link_id(options)
returnmw.ustring.format('[[%s|%s]]%s[[%s%s%s|%s]]',
options.link,options.label,options.separatoror"",
options.prefix,options.id,options.suffixor"",
mw.text.nowiki(options.id)
);
end

--[[ ===============================================================================
Determina se un URL è corretto. Al momento controlla solo la stringa inizia con
prefisso URI valido e che non contenga spazi
TODO: aggiungere controlli più stringenti (vedi en.wiki)
===============================================================================]]
localfunctioncheck_url(url_str)
-- se contiene spazi non può essere un url corretto
ifnil==url_str:match("^%S+$")then
returnfalse;
end
-- Protocol-relative or URL scheme
returnurl_str:sub(1,2)=="//"orurl_str:match("^[^/]*:")~=nil;
end

--[[ ===============================================================================
Rende una stringa sicura per essere usata come descrizione di un url
===============================================================================]]
localfunctionsafe_for_url(str)
ifstr:match("%[%[.-%]%]")~=nilthen
table.insert(z.message_tail,{set_error('wikilink_in_url',{},true)});
end

returnstr:gsub('[%[%]\n]',{
['[']='&#91;',
[']']='&#93;',
['\n']=' '});
end

--[[ ===============================================================================
Formatta un collegamento esterno con controllo degli errori
- URL: url del link esterno
- label: etichetta del link esterno (se non inserita viene usato
URL come etichetta e segnalato l'errore)
- source: parametro in cui è contenuto l'url
===============================================================================]]
localfunctionexternal_link(URL,label,source)
localerror_str="";
ifnotis_set(label)then
label=URL;
ifis_set(source)then
error_str=set_error('bare_url_missing_title',{wrap('parameter',source)},false,"");
else
error(cfg.messages["bare_url_no_origin"]);
end
end
ifnotcheck_url(URL)then
error_str=set_error('bad_url',{},false,"")..error_str;
end
returntable.concat({"[",URL,"",safe_for_url(label),"]",error_str});
end

--[[ ===============================================================================
Ritorna la parte di una stringa data che rappresenta l'anno. Se non riesce ritorna
la stringa vuota
===============================================================================]]
localfunctionselect_year(str)
-- Is the input a simple number?
localnum=tonumber(str);
ifnum~=nilandnum>0andnum<2100andnum==math.floor(num)then
returnstr;
else
-- Use formatDate to interpret more complicated formats
locallang=mw.getContentLanguage();
localgood,result;
good,result=pcall(lang.formatDate,lang,'Y',str)
ifgoodthen
returnresult;
else
-- Can't make sense of this input, return blank.
return"";
end
end
end

--[[ ===============================================================================
Formatta un DOI e controlla per errori
===============================================================================]]
localfunctiondoi(id,inactive)
localcat=""
localhandler=cfg.id_handlers['DOI'];

localtext;
ifis_set(inactive)then
text="[["..handler.link.."|"..handler.label.."]]:"..id;
table.insert(z.error_categories,"Pagine con DOI inattivo dal"..select_year(inactive));
inactive="("..cfg.messages['inactive']..""..inactive..")"
else
text=external_link_id({link=handler.link,label=handler.label,
prefix=handler.prefix,id=id,separator=handler.separator,encode=handler.encode})
inactive=""
end
if(string.sub(id,1,3)~="10.")then
cat=set_error('bad_doi');
end
returntext..inactive..cat
end

--[[ ===============================================================================
Formatta un link a Open library e controlla per errori
===============================================================================]]
localfunctionopen_library(id)
localcode=id:sub(-1,-1)
localhandler=cfg.id_handlers['OL'];
if(code=="A")then
returnexternal_link_id({link=handler.link,label=handler.label,
prefix="http://openlibrary.org/authors/OL",id=id,separator=handler.separator,
encode=handler.encode})
elseif(code=="M")then
returnexternal_link_id({link=handler.link,label=handler.label,
prefix="http://openlibrary.org/books/OL",id=id,separator=handler.separator,
encode=handler.encode})
elseif(code=="W")then
returnexternal_link_id({link=handler.link,label=handler.label,
prefix="http://openlibrary.org/works/OL",id=id,separator=handler.separator,
encode=handler.encode})
else
returnexternal_link_id({link=handler.link,label=handler.label,
prefix="http://openlibrary.org/OL",id=id,separator=handler.separator,
encode=handler.encode})..
' '..set_error('bad_ol');
end
end

--[[ ===============================================================================
Formatta un link alla libreria Opac mediante SBN e controlla per errori
===============================================================================]]
localfunctionsbn(id)
localhandler=cfg.id_handlers['SBN']
localstart_match,end_match,cd1,cd2=string.find(id,'^IT\\ICCU\\(...)\\(%d+)')
ifnot(cd1andcd2)then
start_match,end_match,cd1,cd2=string.find(id,'^IT\\ICCU\\(....)\\(%d+)')
end
ifcd1andcd2then
returnexternal_link_id({link=handler.link,label=handler.label,
prefix='http://opac.sbn.it/bid/',id=id,code_id=cd1..cd2,
encode=handler.encode})
else
returnexternal_link_id({link=handler.link,label=handler.label,
prefix='http://opac.sbn.it/bid/',id=id,
encode=handler.encode})..' '..set_error('bad_sbn')
end
end

--[[ ===============================================================================
Nice Opaque Identifiern utilisé par les formats Ark pour générer une clé
adattato da fr:Module:Biblio/Références
===============================================================================]]
localfunctionark_id(base)
base=tostring(base)
ifbasethen
localxdigits='0123456789bcdfghjkmnpqrstvwxz'
localsum=0
localposition
fori=1,base:len()do
position=xdigits:find(base:sub(i,i),1,true)or1
sum=sum+i*(position-1)
end
localindex=sum%29+1
returnxdigits:sub(index,index)
end
end

--[[ ===============================================================================
Formatta un link alla Bibliothèque Nationale de France e controlla per errori
adattato da fr:Module:Biblio/Références
===============================================================================]]
localfunctionbnf(id)
localhandler=cfg.id_handlers['BNF']
ifidthen
localtxt=id
localerror_code=''
localbnf_id=id:upper():match('BNF(%d+%w)')orid:lower():match('cb(%d+%w)')orid:match('^%d+%w')

ifbnf_idthen
-- bnf contient une suite de chiffres qui peut être un ark valide
localbase=bnf_id:sub(1,8)
ifbnf_id:len()==8then
-- il manque la clé, on l'ajoute
id=base..ark_id('cb'..base)
txt=base
elseifbnf_id:len()>8andbnf_id:sub(9,9)==ark_id('cb'..base)then
-- ark valide
id=bnf_id:sub(1,9)
txt=base
else
-- ark qui semble non valide
id=bnf_id
txt=bnf_id
error_code=set_error('bad_bnf')
end
else
-- le paramètre ne semble pas un ark valide
error_code=set_error('bad_bnf')
end

-- dans tous les cas on renvoie l'adresse, on catégorise juste pour vérifier ce qui ne va pas
returnexternal_link_id({link=handler.link,label=handler.label,prefix=handler.prefix,
id=txt,code_id=bnf_id,separator=handler.separator})..' '..error_code
end
end

--[[ ===============================================================================
Rimuove text e trattini irrilevanti da un numero isbn
===============================================================================]]
localfunctionclean_isbn(isbn_str)
returnisbn_str:gsub("[^-0-9X]","");
end

--[[ ===============================================================================
Determina se una stringa ISBN è valida
===============================================================================]]
localfunctioncheck_isbn(isbn_str)
isbn_str=clean_isbn(isbn_str):gsub("-","");

locallen=isbn_str:len();

iflen~=10andlen~=13then
returnfalse;
end
localtemp=0;
iflen==10then
ifisbn_str:match("^%d*X?$")==nilthenreturnfalse;end
isbn_str={isbn_str:byte(1,len)};
fori,vinipairs(isbn_str)do
ifv==string.byte("X")then
temp=temp+10*(11-i);
else
temp=temp+tonumber(string.char(v))*(11-i);
end
end
returntemp%11==0;
else
ifisbn_str:match("^%d*$")==nilthenreturnfalse;end
isbn_str={isbn_str:byte(1,len)};
fori,vinipairs(isbn_str)do
temp=temp+(3-2*(i%2))*tonumber(string.char(v));
end
returntemp%10==0;
end
end

--[[ ===============================================================================
Ritorna la sola etichetta visibile di un wikilink
===============================================================================]]
localfunctionremove_wikilink(str)
-- Sia [[A|B]] che [[B]] ritornano B
return(str:gsub("%[%[([^%[%]]*)%]%]",function(l)
returnl:gsub("^[^|]*|(.*)$","%1"):gsub("^%s*(.-)%s*$","%1");
end));
end

--[[ ===============================================================================
Ritorna una data e controlla se è nel formato ISO yyyy-mm-dd e in questo caso la
riformatta come dd mmmm yyyy
===============================================================================]]
localfunctionget_date(str)
ifis_set(str)then
local_,_,try_year,try_month,try_day=string.find(str,'^(%d%d%d%d)-(%d%d)-(%d%d)$')
iftry_daythen
localMonth=cfg.months[tonumber(try_month)]
ifMonththen
iftry_day=="01"thentry_day="1°"end
returnstring.format("%s %s %s",try_day,Month,try_year)
end
end
end
returnstr
end

--[[ ===============================================================================
Unisce year, day e month ritornando la data come un'unica stringa.
month è controllato solo se year è definito, e day è controllato solo se month è definito.
Se month è un numero tenta di convertilo nel nome corrispondente (1->gennaio, 2->febbraio...),
altrimenti non lo modifica
===============================================================================]]
localfunctionget_date_yyyy_mm_dd(year,month,day)
localdate=year
ifis_set(date)then
ifis_set(month)then
localmonth=cfg.months[tonumber(month)]ormonth
date=month..""..year
ifis_set(day)then
ifday=="01"orday=="1"thenday="1°"end
date=day..""..date
end
end
returndate
end
return""
end

--[[ ===============================================================================
Suppone che str sia una data ben formata (una delle varianti "gg mm aaaa",
"gg/mm/aaaa" o "gg-mm-aaaa" ) e restituisce l'articolo da anteporre per citarla
come data di accesso/archivio
===============================================================================]]
localfunctionarticle_date(str)
localstart=mw.ustring.sub(str,1,2)
ifin_array(start,{'08','8 ','8-','8/','11'})then
return"l'"
end
return"il"
end

--[[ ===============================================================================
Controlla che la stringa passata sia in un formato ammesso in caso contrario
ritorna il codice di errore
===============================================================================]]
localfunctioncheck_time(str)
localh,m,s=string.match(str,'^(%d+):(%d+):(%d+)$')
ifnot(h)thenh,m,s=string.match(str,'^(%d+) h (%d+) min (%d+) s$')end
ifnot(m)thenm,s=string.match(str,'^(%d+) min (%d+) s$')end
ifnot(m)thenm,s=string.match(str,'^(%d+):(%d+)$')end
ifnot(m)thenm=string.match(str,'^(%d+) min$')end
ifnot(m)thenreturn'time_not_valid'end
iftonumber(m)>=60thenreturn'minutes_wrong'end
ifsandtonumber(s)>=60thenreturn'seconds_wrong'end
ifhandnot(tonumber(s))thenreturn'hour_wrong'end
returnnil
end

--[[ ===============================================================================
Formatta una lista di persone (autori o editori)
===============================================================================]]
localfunctionlist_people(control,people)
localsep=control.sep;
locallastsep=control.lastsep
localtext={}
localetal=control.etal
localcoauthors=control.coauthors
localperson_list={}

fori,personinipairs(people)do
locallast=person.last
ifis_set(last)then
localfullname=""
localfirst=person.first
ifis_set(first)then
ifinvertorderthenfirst,last=last,firstend
fullname=table.concat({first,person.last},' ')
else
fullname=person.last
end
ifis_set(person.link)thenfullname=table.concat({"[[w:",person.link,"|",fullname,"]]"})end
table.insert(person_list,fullname)
end
ifetalthen
break
end
end
localcount=#person_list
localresult=""
ifcount>0then
ifcoauthorsthen
result=table.concat(person_list,sep)
elseifetalthen
result=person_list[1]..cfg.messages['et al']
else
result=mw.text.listToText(person_list,sep,lastsep)
end
end
returnresult,count
end

--[[ ===============================================================================
Genera un id per un ancora CITEREF
===============================================================================]]
localfunctionanchor_id(options)
return"CITEREF"..table.concat(options);
end

--[[ ===============================================================================
Estrae una lista di nomi (autori o editori) dalla lista argomenti
===============================================================================]]
localfunctionextract_names(args,list_name)
localnames={};
locali=1;
locallast;

whiletruedo
last=select_one(args,cfg.aliases[list_name..'-Last'],'redundant_parameters',i);
ifnotis_set(last)then
localfirst=select_one(args,cfg.aliases[list_name..'-First'],'redundant_parameters',i)
ifnotis_set(first)then
break;
else-- nel caso sia definito "nome" ma non "cognome"
names[i]={
last=first,
first='',
link=select_one(args,cfg.aliases[list_name..'-Link'],'redundant_parameters',i),
}
end
else
names[i]={
last=last,
first=select_one(args,cfg.aliases[list_name..'-First'],'redundant_parameters',i),
link=select_one(args,cfg.aliases[list_name..'-Link'],'redundant_parameters',i),
};
end
i=i+1;
end
returnnames;
end

--[[ ===============================================================================
Estrae dagli argomenti i codici bibliografici riconosciuti usando la
tabella cfg.id_handlers
===============================================================================]]
localfunctionextract_ids(args)
localid_list={};
fork,vinpairs(cfg.id_handlers)do
v=select_one(args,v.parameters,'redundant_parameters');
ifis_set(v)then
ifk=='ISBN'thenv=string.gsub(v,'^ISBN%s*','')end-- hack per eliminare l'ISBN ripetuto
id_list[k]=v;
end
end
returnid_list;
end

--[[ ===============================================================================
Formatta gli id bibliografici presenti nella tabella id_list
===============================================================================]]
localfunctionbuild_id_list(id_list,options)
localnew_list,handler={};

localfunctionfallback(k)
return{__index=function(t,i)returncfg.id_handlers[k][i]end}
end;

localfunctioncomp(a,b)
returna[1]<b[1];
end

fork,vinpairs(id_list)do
-- fallback to read-only cfg
localhandler=setmetatable({['id']=v},fallback(k));

ifhandler.mode=='external'then
table.insert(new_list,{handler.label,external_link_id(handler)});
elseifhandler.mode=='internal'then
table.insert(new_list,{handler.label,internal_link_id(handler)});
elseifhandler.mode~='manual'then
error(cfg.messages['unknown_ID_mode']);
elseifk=='DOI'then
table.insert(new_list,{handler.label,doi(v,options.DoiBroken)});
elseifk=='OL'then
table.insert(new_list,{handler.label,open_library(v)});
elseifk=='SBN'then
table.insert(new_list,{handler.label,sbn(v)});
elseifk=='BNF'then
table.insert(new_list,{handler.label,bnf(v)});
elseifk=='ISBN'then
localISBN
ifv=='non esistente'orv=='no'then--la forma lunga per intercettare il valore ritornato dal template NoIsbn
ISBN='ISBN non esistente'
else
ISBN=internal_link_id(handler);
ifnotcheck_isbn(v)andnotis_set(options.IgnoreISBN)then
ISBN=ISBN..set_error('bad_isbn',{},false,"<sup>","</sup>");
end
end
table.insert(new_list,{handler.label,ISBN});
else
error(cfg.messages['unknown_manual_ID']);
end
end
table.sort(new_list,comp);
fork,vinipairs(new_list)do
new_list[k]=v[2];
end

returnnew_list;
end

--[[ ===============================================================================
Genera la citazione
===============================================================================]]
localfunctioncitation0(config,args)
localA=argument_wrapper(args);
locali

localStylename=A['Style']
localStyle=cfg.style
localPPPrefix=(is_set(A['NoPP'])and"")orStyle.ppprefix
localPPrefix=(is_set(A['NoPP'])and"")orStyle.pprefix
Fragment.priority=Style.separator_priority
-- Pick out the relevant fields from the arguments. Different citation templates
-- define different field names for the same underlying things.
-- local Authors = A['Authors'];
locala=extract_names(args,'AuthorList');

localCoauthors=A['Coauthors'];
localOthers=A['Others'];
localEditors=A['Editors'];
locale=extract_names(args,'EditorList');

------------------------------------------------- Get date data
localPublicationDate=A['PublicationDate'];
localLayDate=A['LayDate'];
------------------------------------------------- Get title data
localTitle=A['Title'];
localConference=A['Conference'];
localOrganization=A['Organization']
localTransTitle=A['TransTitle'];
localOriginalTitle=A['OriginalTitle']
-- local TitleNote = A['TitleNote'];
localTitleLink=A['TitleLink'];
localChapter=A['Chapter'];
localChapterLink=A['ChapterLink'];
localTransChapter=A['TransChapter'];
localTitleType=A['TitleType'];
localArchiveURL=A['ArchiveURL'];
localURL=A['URL']
localURLorigin=A:ORIGIN('URL');
localChapterURL=A['ChapterURL'];
localChapterURLorigin=A:ORIGIN('ChapterURL');
localConferenceURL=A['ConferenceURL'];
localConferenceURLorigin=A:ORIGIN('ConferenceURL');
localAbstract=A['Abstract']
localPeriodical=A['Periodical'];

ifis_set(OriginalTitle)andnotis_set(TransTitle)then
TransTitle=Title
Title=OriginalTitle
end

localisPubblicazione=(config.CitationClass=='pubblicazione')or
(config.CitationClass=='testo'andis_set(Periodical))

------------------------------------------------------------------------------
-- Formattazione di Position - contiene la pagina/posizione o punto del video
-- a cui fa riferimento la fonte
------------------------------------------------------------------------------
localPosition=A['Position'];
localPositionOrigin=A:ORIGIN('Position')
ifis_set(Position)then
ifPositionOrigin=="p"then
Position=PPrefix..Position
elseifPositionOrigin=="pp"then
Position=PPPrefix..Position
elseifPositionOrigin~="posizione"then
ifconfig.CitationClass=="libro"andPositionOrigin=="pagine"then
iftonumber(Position)then
Position=PPrefix..Position
elseifstring.find(Position,'^%d')then
Position=PPPrefix..Position
end
elseif(config.CitationClass=="conferenza"orconfig.CitationClass=="pubblicazione")andPositionOrigin=="pagine"then
iftonumber(Position)then
Position=PPrefix..Position
else
Position=PPPrefix..Position
end
elseifPositionOrigin=="pagina"then
Position=PPrefix..Position
else
Position=PPPrefix..Position
end
end
end
localHour=A['Hour']
localMinutes=A['Minutes']
localSeconds=A['Seconds']
localTime=A['Time']
ifin_array(config.CitationClass,{"video","tv","audio"})then
localComposeTime={}
localTimeError={}
ifis_set(Hour)then
ifnotis_set(Minutes)thenTimeError[#TimeError+1]=set_error('need_minutes',{'ora'})end
ifnottonumber(Hour)thenTimeError[#TimeError+1]=set_error('timepar_must_be_integer',{'ora'})end
ComposeTime[#ComposeTime+1]=Hour..' h'
end
ifis_set(Minutes)then
localcheck_error=tonumber(Minutes)
ifnotcheck_errorthen
TimeError[#TimeError+1]=set_error('timepar_must_be_integer',{'minuto'})
elseifcheck_error>60then
TimeError[#TimeError+1]=set_error('minutes_wrong')
end
ComposeTime[#ComposeTime+1]=Minutes..' min'
end
ifis_set(Seconds)then
ifnotis_set(Minutes)thenTimeError[#TimeError+1]=set_error('need_minutes',{'secondo'})end
localcheck_error=tonumber(Seconds)
ifnotcheck_errorthen
TimeError[#TimeError+1]=set_error('timepar_must_be_integer',{'ora'})
elseifcheck_error>60then
TimeError[#TimeError+1]=set_error('seconds_wrong')
end
ComposeTime[#ComposeTime+1]=Seconds..' s'
end
if#ComposeTime>1then
ifis_set(Position)thenTimeError[#TimeError+1]=set_error('time_parameter_conflict')end
Position='a '..table.concat(ComposeTime,' ')
end
ifis_set(Time)then
ifis_set(Position)thenTimeError[#TimeError+1]=set_error('time_parameter_conflict')end
localcheck_error=check_time(Time)
ifcheck_errorthenTimeError[#TimeError+1]=set_error(check_error)end
Position='a '..Time
end
if#TimeError>0thenPosition=Position..""..table.concat(TimeError,",")end
else
ifis_set(Hour)oris_set(Minutes)oris_set(Seconds)oris_set(Time)then
table.insert(z.message_tail,{set_error('not_video_citation',{},true)});
end
end
ifis_set(Position)thenPosition=' '..Positionend

------------------------------------------------------------------------------
-- Formattazione di volume/numero/serie/episodio
------------------------------------------------------------------------------
localSeries=A['Series'];
localVolume=A['Volume'];
localIssue=A['Issue'];
ifconfig.CitationClass=="tv"then
ifis_set(Issue)then
ifis_set(Volume)then
Issue=substitute(cfg.messages['season_episode'],{Volume,Issue})
Volume=''
else
Issue=substitute(cfg.messages['episode'],{Issue})
end
end
else
ifis_set(Volume)then
iftonumber(Volume)orA:ORIGIN('Volume')=="vol"then
Volume="vol."..Volume
end
end
ifis_set(Issue)then
iftonumber(Issue)then
Issue="nº"..Issue
end
end
end

localEdition=A['Edition'];
localPlace=A['Place']
localPublisherName=A['PublisherName'];
localSubscriptionRequired=A['SubscriptionRequired'];
localVia=A['Via'];
-- local Agency = A['Agency'];
localDeadURL=A['DeadURL']
localLanguage=A['Language'];
localFormat=A['Format'];
localRef=A['Ref'];

localDoiBroken=A['DoiBroken'];
localID=A['ID'];
localIgnoreISBN=A['IgnoreISBN'];
localQuote=A['Quote'];
localsepc=Style.sep
localsepcspace=sepc..""
localPostScript=first_set(A['PostScript'],Style['postscript'])
localno_tracking_cats=A['NoTracking'];
localuse_lowercase=(sepc~='.');
localthis_page=mw.title.getCurrentTitle();--Also used for COinS

localID_list=extract_ids(args);
if(isPubblicazione)then
ifnotis_set(URL)andis_set(ID_list['PMC'])then
localEmbargo=A['Embargo'];
ifis_set(Embargo)then
locallang=mw.getContentLanguage();
localgood1,result1,good2,result2;
good1,result1=pcall(lang.formatDate,lang,'U',Embargo);
good2,result2=pcall(lang.formatDate,lang,'U');

ifgood1andgood2andtonumber(result1)<tonumber(result2)then
URL="http:// ncbi.nlm.nih.gov/pmc/articles/PMC"..ID_list['PMC'];
URLorigin=cfg.id_handlers['PMC'].parameters[1];
end
else
URL="http:// ncbi.nlm.nih.gov/pmc/articles/PMC"..ID_list['PMC'];
URLorigin=cfg.id_handlers['PMC'].parameters[1];
end
end
end
ID_list=build_id_list(ID_list,{DoiBroken=DoiBroken,IgnoreISBN=IgnoreISBN});

localStation=A['Station'];
ifis_set(Station)then
localwkStation=A['StationLink']
ifis_set(wkStation)then
Station='[['..wkStation..'|'..Station..']]'
end
end
ifconfig.CitationClass=="tv"then
Chapter=Title;
ChapterLink=TitleLink;
TransChapter=TransTitle;
Title=Series;
TitleLink=A['SeriesLink'];
TransTitle='';
Series='';
end

------------------------------------------------------------------------------
-- Se compare uno dei parametri legati a una pubblicazione periodica (opera, rivista, ec...)
-- e non è definito capitolo, ma solo titolo sposto titolo a capitolo
------------------------------------------------------------------------------
ifis_set(Periodical)andnotis_set(Chapter)andis_set(Title)then
Chapter=Title;
ChapterLink=TitleLink;
TransChapter=TransTitle;
Title='';
TitleLink='';
TransTitle='';
end

------------------------------------------------------------------------------
-- Se opera/sito non è specificata, nel caso dei siti usa il dominio dell'URL
------------------------------------------------------------------------------
ifconfig.CitationClass=="web"andnotis_set(Periodical)andnotis_set(PublisherName)andis_set(URL)then
Periodical=mw.ustring.match(URL,"//([^/#%?]*)")or''
-- tolgo anche eventuale
ifstring.find(Periodical,"^[Ww][Ww][Ww]%.")then
Periodical=mw.ustring.sub(Periodical,5)
end
-- evito ripetizione se il dominio è stato usato come titolo o editore
ifPeriodicalandmw.ustring.lower(Titleor'')==mw.ustring.lower(Periodical)then
Periodical=nil
end
end

------------------------------------------------------------------------------
-- Recupero e formatto lista autori
------------------------------------------------------------------------------
localAuthorSeparator=Style.peoplesep
localcontrol={
sep=AuthorSeparator,
maximum=Style.maximum_authors,
lastsep=Style.lastsepauthor,
invertorder=Style.invertorder,
etal=false,
coauthors=false,
};
localEtal=A['Etal']
-- If the coauthor field is also used, prevent adding ''et al.''
ifis_set(Coauthors)then
control.coauthors=true
elseifis_set(Etal)then
control.etal=true
end
localAuthors=list_people(control,a)
ifnotis_set(Authors)andis_set(Coauthors)then-- se non sono stati compilati campi autore, ma solo coautori
Authors=Coauthors
Coauthors=""
elseifis_set(Coauthors)then
Authors=table.concat({Authors,AuthorSeparator,Coauthors})
end

------------------------------------------------------------------------------
-- Recupero e formatto lista curatori
------------------------------------------------------------------------------
localEditorCount,msg_editors
localCuratoriEtal=A['Etalcuratori']
control.coauthors=false
ifis_set(CuratoriEtal)then
control.etal=true
else
control.etal=false
end
ifis_set(Editors)then
msg_editors='editors'
else
Editors,EditorCount=list_people(control,e)
ifis_set(Editors)then
ifEditorCount<=1thenmsg_editors='editor'elsemsg_editors='editors'end
end
end
------------------------------------------------------------------------------
-- Se non sono definiti autori sostituisco con curatori
------------------------------------------------------------------------------
ifnotis_set(Authors)andis_set(Editors)then
Authors=Editors
Editors=""
end

------------------------------------------------------------------------------
-- Se conferenza aggiungo il campo Organizzazione
------------------------------------------------------------------------------
ifconfig.CitationClass=='conferenza'then
ifis_set(Authors)andis_set(Organization)then
Authors=table.concat({Authors,', ',Organization})
elseifis_set(Organization)then
Authors=Organization
end
Organization=""
end

------------------------------------------------------------------------------
-- Formatto la data
------------------------------------------------------------------------------
localDate=get_date(A['Date'])
localYear=A['Year']
ifnotis_set(Date)thenDate=get_date_yyyy_mm_dd(Year,A['Month'],A['Day'])end
localOrigDate=get_date(A['OrigDate'])
ifnotis_set(OrigDate)thenOrigDate=get_date_yyyy_mm_dd(A['OrigYear'],A['OrigMonth'],A['OrigDay'])end
localAccessDate=get_date(A['AccessDate'])
ifnotis_set(AccessDate)thenAccessDate=get_date_yyyy_mm_dd(A['AccessYear'],A['AccessMonth'],A['AccessDay'])end
localArchiveDate=get_date(A['ArchiveDate']);
ifis_set(OrigDate)andnotis_set(Date)then
Date=OrigDate
OrigDate=""
end
OrigDate=is_set(OrigDate)and(""..wrap('origdate',OrigDate))or"";

ifin_array(PublicationDate,{Date,Year})thenPublicationDate=''end
ifnotis_set(Date)andis_set(PublicationDate)then
Date=PublicationDate;
PublicationDate='';
end

-- Captures the value for Date prior to adding parens or other textual transformations
localDateIn=Date;
ifnotis_set(URL)and
notis_set(ChapterURL)and
notis_set(ArchiveURL)and
notis_set(ConferenceURL)then
-- Test if cite web is called without giving a URL
if(config.CitationClass=="web")then
table.insert(z.message_tail,{set_error('cite_web_url',{},true)});
end
-- Test if accessdate is given without giving a URL
ifis_set(AccessDate)then
table.insert(z.message_tail,{set_error('accessdate_missing_url',{},true)});
AccessDate='';
end
-- Test if format is given without giving a URL
ifis_set(Format)then
Format=Format..set_error('format_missing_url');
end
end

-- Test if citation has no title
ifnotis_set(Chapter)and
notis_set(Title)and
notis_set(Periodical)and
notis_set(Conference)and
notis_set(TransTitle)and
notis_set(TransChapter)then
table.insert(z.message_tail,{set_error('citation_missing_title',{},true)});
end

-- Se il formato file non è specificato, prova a ricavarlo dalla fine dell'URL
if(is_set(URL)oris_set(ChapterURL))andnotis_set(Format)then
localtry_format=mw.ustring.match((is_set(ChapterURL)andChapterURL)orURL,"^.*%.(.+)$")or''
ifcfg.external_link_type[try_format:lower()]then
Format=try_format
end
end

-- Se il formato esterno è tra quelli previsti imita lo stile dei template {{PDF}} o {{doc}}
ifis_set(Format)then
localf=cfg.external_link_type[Format:lower()]
iffthen
Format=mw.ustring.format(' (<span style= "font-weight: bolder; font-size: smaller;>[[%s|%s]]</span>)',f.link,f.label)
else
table.insert(z.message_tail,{set_error('unknown_format',Format,true)});
Format=mw.ustring.format(' (%s)',Format)
end
else
Format=""
end

localOriginalURL=URL
DeadURL=DeadURL:lower();
ifis_set(ArchiveURL)then
if(DeadURL~="no")then
URL=ArchiveURL
URLorigin=A:ORIGIN('ArchiveURL')
end
end

---------------------------------------------------------------
-- se pubblicazione controlla per i parametro abstract
--------------------------------------------------------------
ifis_set(Abstract)then
ifisPubblicazionethen
ifis_set(ChapterURL)then
TitleType=external_link(ChapterURL,'abstract')
ChapterURL=""
ifnotis_set(URL)thenFormat=""end
elseifis_set(URL)then
TitleType=external_link(URL,'abstract')
URL=""
else
Abstract=''
end
else
Abstract=""
end
else
Abstract=""
end
TitleType=is_set(TitleType)and("("..TitleType..")")or"";

---------------------------------------------------------------
-- Format chapter / article title
---------------------------------------------------------------
localTransError=""
ifis_set(TransChapter)then
ifnotis_set(Chapter)then
TransError=""..set_error('trans_missing_chapter')
Chapter=TransChapter
TransChapter=""
else
TransChapter=wrap('trans-italic-title',TransChapter)
end
end
Chapter=wrap('italic-title',Chapter);
ifis_set(TransChapter)thenChapter=Chapter..""..TransChapterend
ifis_set(Chapter)then
ifis_set(ChapterLink)then
Chapter=table.concat({"[[",ChapterLink,"|",Chapter,"]]"})
elseifis_set(ChapterURL)then
Chapter=external_link(ChapterURL,Chapter)..TransError;
ifnotis_set(URL)then--se è settato URL conservo Format per inserirlo dopo questo
Chapter=Chapter..Format;
Format="";
end
elseifis_set(URL)then
Chapter=external_link(URL,Chapter)..TransError..Format;
URL="";
Format="";
else
Chapter=Chapter..TransError;
end
elseifis_set(ChapterURL)then
Chapter=external_link(ChapterURL,nil,ChapterURLorigin)..TransError
end

---------------------------------------------------------------
-- Format main title
---------------------------------------------------------------
TransError="";
ifis_set(TransTitle)then
ifnotis_set(Title)then
TransError=""..set_error('trans_missing_title')
Title=TransTitle
TransTitle=""
else
TransTitle=wrap('trans-italic-title',TransTitle)
end
end
Title=wrap('italic-title',Title)
ifis_set(TransTitle)thenTitle=Title..""..TransTitleend
ifis_set(Title)then
ifis_set(TitleLink)then
Title="[["..TitleLink.."|"..Title.."]]"
elseifis_set(URL)then
Title=external_link(URL,Title)..TransError..Format
URL="";
Format="";
else
Title=Title..TransError;
end
end
---------------------------------------------------------------
-- Format Conference
---------------------------------------------------------------
ifis_set(Conference)then
Conference=wrap('italic-title',Conference)
ifis_set(ConferenceURL)then
Conference=external_link(ConferenceURL,Conference);
end
elseifis_set(ConferenceURL)then
Conference=external_link(ConferenceURL,nil,ConferenceURLorigin);
end

---------------------------------------------------------------
-- Compone la stringa del linguaggio
---------------------------------------------------------------
localLanguage_code=""
ifis_set(Language)then
ifLanguage:sub(1,1)=="("then
Language_code=Language
else
localframe={return_error='true',usacodice='sì'}
forlinguainmw.ustring.gmatch(Language,"%S+")do
frame[#frame+1]=lingua
end
if#frame>1or(#frame==1andframe[1]:lower()~="it")then
locallg_error
locallg=require("Modulo:Linguaggi");
Language_code,lg_error=lg.lingue(frame)
iflg_errorand#lg_error>0then
localerror_string=mw.text.listToText(lg_error,",","e")
table.insert(z.message_tail,{set_error('unknown_language',{error_string},true)});
end
end
end
end

ifis_set(Edition)then
ifA:ORIGIN('Edition')=="ed"ortonumber(Edition)then
Edition=Edition.."ª ed."
end
end

-- se URL non è stato consumato da un capitolo/titolo emette errore
ifis_set(URL)then
URL=""..external_link(URL,nil,URLorigin);
end

--Aggiungo le virgolette alla citazione-
ifis_set(Quote)then
Quote=wrap('quoted-text',Quote);
end
---------------------------------------------------------------
-- Parametro via e subscription
---------------------------------------------------------------
ifis_set(Via)then
ifis_set(SubscriptionRequired)then
Via=wrap('viasubscription',Via);
else
Via=wrap('via',Via);
end
elseifis_set(SubscriptionRequired)then
Via=wrap('subscription')
end

---------------------------------------------------------------
-- Formattazione dati di accesso/url di archivio
---------------------------------------------------------------
ifis_set(AccessDate)then
AccessDate=substitute(cfg.messages['retrieved'],{AccessDate,article_date(AccessDate)})
end
localArchived
ifis_set(ArchiveURL)then
ifnotis_set(ArchiveDate)then
ArchiveDate=set_error('archive_missing_date');
end
ArchiveURL2=A['ArchiveURL2']
ifis_set(ArchiveURL2)then
ArchiveDate2=A['ArchiveDate2']
ifnotis_set(ArchiveDate2)then
ArchiveDate2=set_error('archive_missing_date2');
end
end
ifDeadURL=="no"then
Archived=substitute(cfg.messages['archived-not-dead'],
{external_link(ArchiveURL,cfg.messages['archived']),ArchiveDate,article_date(ArchiveDate)});
ifnotis_set(OriginalURL)then
Archived=Archived..""..set_error('archive_missing_url');
end
elseifis_set(OriginalURL)then
Archived=substitute(cfg.messages['archived-dead'],
{OriginalURL,ArchiveDate,article_date(ArchiveDate)});
else
Archived=substitute(cfg.messages['archived-missing'],
{set_error('archive_missing_url'),ArchiveDate,article_date(ArchiveDate)});
end
ifis_set(ArchiveURL2)then
Archived=Archived.."."..substitute(cfg.messages['archived-second-copy'],
{external_link(ArchiveURL2,cfg.messages['archived2']),ArchiveDate2,article_date(ArchiveDate2)});
end
else
Archived=""
end

---------------------------------------------------------------
-- Data originale se presente (in ordine di preferenza dopo
-- la data di pubblicazione, quindi l'editore, il luogo di pubblicazione, )
---------------------------------------------------------------
ifis_set(OrigDate)then
ifis_set(Date)then
Date=Date..""..OrigDate
elseifis_set(PublisherName)then
PublisherName=PublisherName..""..OrigDate
elseifis_set(Plase)then
Place=Place..""..OrigDate
else
Date=OrigDate
end
end

-- Several of the above rely upon detecting this as nil, so do it last.
ifis_set(Periodical)thenPeriodical=wrap('italic-title',Periodical)end
ifconfig.CitationClass=="news"andis_set(Place)then
ifis_set(Periodical)then
Periodical=table.concat({Periodical,' (',Place,')'})
Place=""
elseifis_set(Title)then
Title=table.concat({Title,' (',Place,')'})
Place=""
end
end

---------------------------------------------------------------
-- Combino insieme i vari componenti della citazione
---------------------------------------------------------------

localfragment_Title
ifis_set(Title)then
fragment_Title=Fragment.new({Title,Format,TitleType},' '):last(",")
else
fragment_Title=Fragment.new({})
ifis_set(Chapter)then
Chapter=tostring(Fragment.new({Chapter,Format,TitleType},' '):last(""))
end
end

localfragment_citation
ifconfig.CitationClass=="tv"then
ifis_set(Chapter)then
fragment_Title:last(":"):append(Fragment.new({Issue,Chapter},sepc))
Issue=""
end
fragment_citation=Fragment.new({Authors},sepc)
fragment_citation:append(fragment_Title)
else
ifis_set(Authors)andis_set(Editors)andis_set(Title)andnotis_set(Chapter)then
Editors='a cura di '..Editors
fragment_citation=Fragment.new({Authors},sepc)
fragment_citation:appends({fragment_Title,Editors})
else
ifis_set(msg_editors)then
ifis_set(Editors)then
Editors=wrap(msg_editors,Editors)
else
Authors=wrap(msg_editors,Authors)
end
end
fragment_citation=Fragment.new({Authors,Chapter},sepc)
ifChapter~=""orEditors~=""then
ifA:ORIGIN('Periodical')=='sito'then-- antepone "su" anzichè "in" per i siti web
fragment_citation:last("su")
else
fragment_citation:last("in")
end
end
fragment_citation:appends({Editors,fragment_Title})
end
end
fragment_citation:appends({Conference,Periodical,Others,Series,
Volume,Issue,Edition,Place,PublisherName,Station,Date,Position})
localfragment_ID_list=Fragment.new(ID_list,sepc):append(ID):start(",")
localfragment_URL=Fragment.new(URL):start(",")
localfragment_AccessInfo=Fragment.new({AccessDate,Via,Archived},""):start(".")
localfragment_Quote=Fragment.new({Quote}):start(".")
fragment_citation:appends({fragment_ID_list,fragment_URL,fragment_AccessInfo,fragment_Quote})
ifPostScript=='nessuno'then
fragment_citation:last("nothing")
else
fragment_citation:last("..")
end
fragment_citation:start("")
localtext=Language_code..tostring(fragment_citation)
--aggiungo l'icona per cita video
ifconfig.CitationClass=="video"thentext=cfg.messages['icon_video']..textend
ifconfig.CitationClass=="audio"thentext=cfg.messages['icon_audio']..textend

-- Now enclose the whole thing in a <span/> element
localoptions={};

ifis_set(config.CitationClass)andconfig.CitationClass~="citation"then
options.class="citation"..config.CitationClass;
else
options.class="citation";
end

-- if string.len(text:gsub( "<span[^>/]*>.-</span>", "" ):gsub( "%b<>", "" )) <= 2 then
-- z.error_categories = {};
-- text = set_error('empty_citation');
-- z.message_tail = {};
-- end

ifis_set(Ref)then
text=table.concat({'<cite id= "CITEREF',Ref,--mw.uri.anchorEncode('CITEREF'.. Ref),
' "class=" ',mw.text.nowiki(options.class),' "style=" font-style:normal ">',text,"</cite>"})
else
text=table.concat({'<cite class= "',mw.text.nowiki(options.class),' "style=" font-style:normal ">',text,"</cite>"})
end

localempty_span='<span style= "display:none;" > </span>';

if#z.message_tail~=0then
text=text.."";
fori,vinipairs(z.message_tail)do
ifis_set(v[1])then
ifi==#z.message_tailthen
text=text..error_comment(v[1],v[2]);
else
text=text..error_comment(v[1]..";",v[2]);
end
end
end
end

-- Chek to insert category error
ifnotis_set(no_tracking_cats)then
fork,vinpairs(cfg.uncategorized_namespaces)do
ifthis_page.nsText==vthen
no_tracking_cats="true";
break;
end
end
end
no_tracking_cats=no_tracking_cats:lower();
ifin_array(no_tracking_cats,{"","no","false","n"})then
for_,vinipairs(z.error_categories)do
text=text..'[[Categoria:'..v..']]';
end
end

returntext
end

--[[ ===============================================================================
Funzione di interfaccia per la generazione della citazione, usata dai vari template
cita libro, cita news, ecc...
===============================================================================]]
functionz.citation(frame)
localpframe=frame:getParent()

localargs={};
localsuggestions={};
localerror_text,error_state;

localconfig={};
fork,vinpairs(frame.args)do
config[k]=v;
args[k]=v;
end
ifconfig['ignore_parent']=='s'then
pframe.args={}
end
-- copy unnamed parameter to named parameter
locallastunnamed=0
ifcfg.unnamed_parameter[config.CitationClass]then
fori,vinipairs(cfg.unnamed_parameter[config.CitationClass])do
ifpframe.args[i]then
localargs_value=mw.text.trim(pframe.args[i])
ifargs_value~=""then
args[v]=args_value
end
lastunnamed=i
else
break
end
end
end
fork,vinpairs(pframe.args)do
ifv~=''then
ifnotvalidate(k)then
error_text="";
iftype(k)~='string'then
-- Exclude empty numbered parameters
ifv:match("%S+")~=nilandtonumber(k)>lastunnamedandlastunnamed>0then
error_text,error_state=set_error('text_ignored',{v},true);
end
elseifvalidate(k:lower())then
error_text,error_state=set_error('parameter_ignored_suggest',{k,k:lower()},true);
else
if#suggestions==0then
suggestions=mw.loadData('Modulo:Citazione/Suggerimenti');
end
ifsuggestions[k:lower()]~=nilthen
error_text,error_state=set_error('parameter_ignored_suggest',{k,suggestions[k:lower()]},true);
else
error_text,error_state=set_error('parameter_ignored',{k},true);
end
end
iferror_text~=''then
table.insert(z.message_tail,{error_text,error_state});
end
end
args[k]=v;
elseifargs[k]~=nilthen
args[k]=v;
end
end

-- hack per l'uso che fanno cita google books e youtube del parametro id
ifargs.idandargs.id~=''then
ifin_array(config.CitationClass,{"googlebooks","video"})then
args.id=nil
end
end
returncitation0(config,args)
end

-- Elenco i formati di documenti gestiti
functionz.list_external_links(frame)
localrows={'{| class = "wikitable sortable"\n!codice!!collegamento!!visualizzato come'}
localkeys={}
forkey,_inpairs(cfg.external_link_type)do
keys[#keys+1]=key
end
table.sort(keys)
for_,keyinipairs(keys)do
rows[#rows+1]='|-\n|'..key..'|| [['..cfg.external_link_type[key].link..
']] || (<span style= "font-weight: bolder; font-size: smaller;" >'..
cfg.external_link_type[key].label..'</span>)'
end
rows[#rows+1]="|}"
returntable.concat(rows,'\n')
end

returnz