Module:Sandbox/Daimona Eaytoy/FontToSpan

< Module:Sandbox
Revision as of 14:28, 25 Ocak 2018 by imported>Daimona Eaytoy (Importing from it.wiki, module to semi-automatically convert font to span tags)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation for this module may be created at Module:Sandbox/Daimona Eaytoy/FontToSpan/doc

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