Modulo:Font to span
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Font to span/man (modifica • cronologia)
Sandbox: Modulo:Font to span/Sandbox (modifica•cronologia) • Test: Modulo:Font to span/Test (modifica•cronologia)
La funzione principale di questo modulo è la conversione dei tag font
, deprecati in HTML 5, in tag span
con opportuno stile. Per utilizzarlo (sempre e comunque in subst) è necessario rintracciare un tag font di apertura e il corrispettivo tag di chiusura con un'espressione regolare e inserire tutto il testo trovato come primo parametro. Ad esempio, è possibile procedere così:
- Utilizzare l'espressione regolare
<font[^>]+>[^<]+<\/font>
per trovare il testo da sostituire. - Sostituirlo con
{{subst:#invoke:Font to span|main|1=$&}}
, dove$&
è l'intero testo trovato; occorre ricordarsi di inserire1=
altrimenti i simboli di uguale contenuti nel tag generano errore.
Il modulo provvede da solo alle operazioni necessarie, convertendo i parametri di dimensione, colore e face del testo. Inoltre, se all'interno dei tag si trova solo un wikilink o un link esterno con titolo, il tag viene spostato dentro al link per mantenere il colore voluto. L'unico caso non supportato è quello in cui i tag contengano soltano un link esterno senza titolo, per i quali sembra non esserci una soluzione semplice. Occorre inoltre fare particolare attenzione al subst, evitando di effettuare la sostituzione all'interno di tag <ref>...</ref>
o <includeonly>...</includeonly>
.
È inoltre possibile utilizzare il modulo per incorporare due tag, siano essi font
o span
(anche misti), situati uno dentro l'altro con lo stesso testo in mezzo. In questo caso, il modulo provvede ad estrarre dai due tag lo stile effettivo da utilizzare, cercandolo rispettivamente in:
- Style del tag internoParametri sparsi nel tag internoStyle del tag esternoParametri sparsi nel tag esterno
Trovati i parametri finali li converte e semplifica come nella modalità principale e restituisce un unico tag con i parametri corretti. Per utilizzare questa funzionalità, è necessaria un'espressione regolare che trovi tutto il testo dall'apertura del tag esterno alla sua chiusura.
Ad esempio, sul testo
<span style="color:green;font-family:Verdana"><font face=Monospace size=2>Testo di prova senza alcun significato messo qui come esempio</font></span>
è necessaria una regex come (<(font|span)[^>]+>)(<(font|span)[^>]+>)[^<]+<\/\4><\/\2>
, con un gruppo catturante sul tag esterno e uno sul tag interno. Come replace occorre chiamare il modulo nel seguente modo: {{subst:#invoke:Font to span|sempl|1=$1|2=$3|3=$&}}
. Il risultato sarà <span style="color:green;font-family:Monospace;font-size:small">Testo di prova senza alcun significato messo qui come esempio</span>
- Nota
- Le dimensioni troppo grandi (+4, 7 e maggiori) vengono convertite in un formato fisso espresso in pixel, anziché variabile come per le altre.
--ToDo: Aggiungere riconoscimento degli apici oltre alle virgolette in tutte le stringhe
local p={};
--funzione di estrazione per utilizzo multiplo
local function extract(x)
face=string.match(x, "face%s*=%s*([%d%aæ,]+)") or string.match(x, 'face%s*=%s*"%s*([^"]+)"')
size=string.match(x, 'size%s*=%s*"?%s*([-+]?%d+[pxtem%%]*)"?') or string.match(x, 'size%s*=%s*"?%s*([%a-]+)"?')
color=string.match(x, 'color%s*=%s*"?%s*(rgb%([^)]+%))"?') or string.match(x, 'color%s*=%s*"?%s*(#?%w+)"?')
style=string.match(x, 'style%s*=%s*"([^"]+)"')
return {face, size, color, style}
end
--funzione per ricostruire lo style
local function build(a,b,c,d)
--Mette insieme lo style
if d==nil then d="" end
if string.match(d, "[^;]$") then d = d .. ";" end
if a~=nil then d=d .. "color:" .. a .. ";" end
if b~=nil then d=d .. "font-size:" .. b .. ";" end
if c~=nil then d=d .. "font-family:" .. c .. ";" end
--Via le virgolette conclusive e restituisce style impacchettato
return string.gsub(d, ";+$", "")
end
local function convert(a,type)
if type=="size" then
--riporto valori fantasiosi di size a quelli reali
z=tonumber(string.match(a, "(%d+) *pt")) or tonumber(a)
if z~=nil then
if z>7 then a="7"
elseif z<-2 then a="-2"
elseif z>4 and string.match(a, "^%+%d$") then a="+4" end
end
--tabella conversione size
stab = {
['1'] = 'x-small',
['2'] = 'small',
['3'] = 'medium',
['4'] = 'large',
['5'] = 'x-large',
['6'] = 'xx-large',
['7'] = '48px',
['-2'] = 'x-small',
['-1'] = 'small',
['+1'] = 'large',
['+2'] = 'x-large',
['+3'] = 'xx-large',
['+4'] = '48px'
}
a = stab[a] or a
end
if type=="color" then
--via gli spazi messi fantasiosamente e l'ancor più fantasioso "solid"
a = string.gsub(a, " ", "");
a = string.gsub(a, "solid", "");
--aggiunge cancelletto a colore se in formato hex e sottinteso. Il pattern è molto brutale ma funziona perché non esistono nomi di colore che lo rispettano
if string.match(a, "^[a-f0-9]+$") then a = "#" .. a end
--toglie il cancelletto dai colori non hex (sì, a giro c'è anche questo)
if string.match(a, "^%#[a-f0-9]*[g-z]") then a = string.gsub(a, "%#", "") end
--tabella semplificazione colore per i casi più semplici
ctab = {
['#ff0000'] = 'red',
['#ffc0cb'] = 'pink',
['#ffa500'] = 'orange',
['#ffff00'] = 'yellow',
['#800080'] = 'purple',
['#008000'] = 'green',
['#0000ff'] = 'blue',
['#a52a2a'] = 'brown',
['#ffffff'] = 'white',
['#808080'] = 'gray',
['#000000'] = 'black'
}
a = ctab[a] or a
end
return a
end
function p.main(frame)
str=frame.args[1]
local substype
--substype per eventuale spostamento testo
if string.match(str, "<font[^>]+>%[%[[^%]]+]]<%/font>") then
substype=1; --solo wikilink
elseif string.match(str, "<font[^>]+>%[http[^%]]+ [^%]]+]<%/font>") or string.match(str, "<font[^>]+>%[\{\{fullurl[^%]]+ [^%]]+]<%/font>") then
substype=2; --solo link esterno CON TITOLO
elseif string.match(str, "<font[^>]+>%[http[^%] ]+]<%/font>") or string.match(str, "<font[^>]+>%[\{\{fullurl[^%] ]+]<%/font>") then
return str; --solo link esterno SENZA TITOLO: il font colora il numero progressivo dall'esterno, lo span no; non ho trovato un modo per colorarlo con span interno.
end --negli altri casi i risultati sono equivalenti
--riduzione stringa al solo font di apertura e minuscolizza il tutto
s=mw.ustring.lower(string.sub(str,1,string.find(str, ">")));
--estrazione attributi
attr=extract(s)
--torno ad attributi con nome per semplicità
face=attr[1]
size=attr[2]
color=attr[3]
style=attr[4]
--conversione size e aggiustamento numeri
if size~=nil then size=convert(size, "size") end
--uscita di sicurezza
if size == "+4" or size =="7" then return str end --font troppo grande, non sono riuscito a convertirlo
--conversione color ed eventuale aggiustamento cancelletto
if color~=nil then color = convert(color, "color") end
-- elimina parametri duplicati, lascia quello in style
if style~=nil then
style=string.gsub(style, "background%-color", "background%-clor") --workaround per evitare match sul bgcol
if color~=nil and string.match(style, "color:") then color=nil end
if size~=nil and string.match(style, "font%-size:") then size=nil end
if face~=nil and string.match(style, "font%-family:") then face=nil end
style=string.gsub(style, "background%-clor", "background%-color") --annullo il workaround
end
--Costruisce lo style
style=build(color, size, face, style)
--Controllo "di sicurezza": se lo style è (quasi) vuoto restituisce il testo di partenza e buonanotte
if string.match(style, "^%s*$") then return str end
--Costruisce lo span e ci inserisce il testo (substype 0)
span='<span style="' .. style .. '">'
text=string.gsub(str, "<%/?[Ff][Oo][Nn][Tt][^>]*>", "")
result= span .. text .. "</span>"
--Spostamento per substype = 1
if substype==1 then
wl=string.sub(str,string.find(str, "%[%["),string.find(str, "]]"))
if string.match(wl, "|") then
--Wikilink con pipe
wl1=string.sub(wl,1,string.find(wl, "|"))
wl2=string.gsub(string.sub(wl,string.find(wl, "|"),string.find(wl, "]")), "[|%]]", "")
result=wl1 .. span .. wl2 .. "</span>]]"
else
--Wikilink senza pipe, lo aggiunge
wl1=string.gsub(wl, "[%]%[]", "")
result="[[" .. wl1 .. "|" .. span .. wl1 .. "</span>]]"
end
elseif substype==2 then
l=string.sub(str,string.find(str, "%["),string.find(str, "]"))
l1=string.sub(l, 1, string.find(l, " "));
l2=string.sub(string.gsub(string.sub(l,string.find(l, " "),string.find(l, "]")), "%]", ""), 2)
result=l1 .. span ..l2 .. "</span>]"
end
return result
end
--funzione per accorpare due font/span con lo stesso testo in mezzo
function p.sempl(frame)
str=frame.args[3]
--estrazione parametri sparsi
x=extract(mw.ustring.lower(frame.args[1]))
y=extract(mw.ustring.lower(frame.args[2]))
--estrazione parametri dal primo style
if x[4]~=nil then
x[4]=string.gsub(x[4], "background%-color", "background%-clor") --workaround per evitare match sul bgcol
c1=string.match(x[4], 'color:([^;"]+)')
s1=string.match(x[4], 'font%-size:([^;"]+)')
f1=string.match(x[4], 'font%-family:([^;"]+)')
x[4]=string.gsub(string.gsub(string.gsub(x[4], 'font%-family:([^;"]+)', ""), 'font%-size:([^;"]+)', ""), 'color:([^;"]+)', "")
x[4]=string.gsub(x[4], "background%-clor", "background%-color") --annullo il workaround
end
--estrazione parametri dal secondo style
if y[4]~=nil then
y[4]=string.gsub(y[4], "background%-color", "background%-clor") --workaround per evitare match sul bgcol
c2=string.match(y[4], 'color:([^;"]+)')
s2=string.match(y[4], 'font%-size:([^;"]+)')
f2=string.match(y[4], 'font%-family:([^;"]+)')
y[4]=string.gsub(string.gsub(string.gsub(y[4], 'font%-family:([^;"]+)', ""), 'font%-size:([^;"]+)', ""), 'color:([^;"]+)', "")
y[4]=string.gsub(y[4], "background%-clor", "background%-color") --annullo il workaround
end
--Parametro univoco, ordine di priorità: style dentro, tag dentro, style fuori, tag fuori
f=f2 or y[1] or f1 or x[1]
s=s2 or y[2] or s1 or x[2]
c=c2 or y[3] or c1 or x[3]
--conversione size e aggiustamento numeri
if s~=nil then s=convert(s, "size") end
--uscita di sicurezza
if s == "+4" or s =="7" then return str end --font troppo grande, non sono riuscito a convertirlo
--conversione color ed eventuale aggiustamento cancelletto
if c~=nil then c = convert(c, "color") end
--Scorre i due style per trovare parametri uguali
if x[4]~=nil and y[4]~=nil then
--liste di attributi
it1= string.gmatch(x[4], "([%a-]+:)")
it2= string.gmatch(y[4], "([%a-]+:)")
corr={}; --table vuota di corrispondenze
for i in it1 do
for j in it2 do
if i==j then table.insert(corr, i) end --aggiunge il match alle corrispondenze
end
it2= string.gmatch(y[4], "([%a-]+:)") --ripristina iteratore per altri giri
end
--elimina le corrispondenze e relativo valore dal tag esterno
for i,v in ipairs(corr) do
x[4]=string.gsub(x[4], v.."[^;]+;*", "");
end
--formatta i due style eliminando spazi e punti e virgola superflui
x[4]=string.gsub(string.gsub(x[4], ";[ ;]+", ";"), "^[ ;]+", "")
y[4]=string.gsub(string.gsub(y[4], ";[ ;]+", ";"), "^[ ;]+", "")
--unisce ciò che rimane dei due style
if string.match(x[4], "[^;]$") then x[4] = x[4] .. ";" end
stile=x[4]..y[4]
elseif x[4]~=nil then
stile=string.gsub(string.gsub(x[4], ";[ ;]+", ";"), "^[ ;]+", "")
elseif y[4]~=nil then
stile=string.gsub(string.gsub(y[4], ";[ ;]+", ";"), "^[ ;]+", "")
end
--Ottiene uno style singolo con tutti e soli i parametri da mantenere
sty=build(c,s,f,stile)
--Seconda uscita di sicurezza
if string.match(sty, "^%s*$") then return str end
--Costruisce lo span unico, ci rimette dentro il testo e lo restituisce
text=string.gsub(string.gsub(str, "<%/?[Ff][Oo][Nn][Tt][^>]*>", ""), "<%/?[Ss][Pp][Aa][Nn][^>]*>", "")
return '<span style="' .. sty .. '">' .. text .. "</span>"
end
return p