Documentación del módulo
Por favor, añade las categorías a la subpágina de documentación.
(subpáginas - enlaces)
local p = {}
local Wikidata = require('Módulo:Wikidata')
local QID = mw.wikibase.getEntityIdForCurrentPage()
local Str = require('Módulo:String')
local Args = require('Módulo:Arguments')
local Enlaces = require('Módulo:Enlaces')
local categorias = ''
local lang = mw.language.new('es')

--parámetros reconocidos. 1 = vigente, 0 = obsoleto. En orden alfabético:
local params = {['ano']=1,['anterior']=1,['autor']=1,["bilingüe"]=1,['catálogo']=0,['commons']=1,['commonscat']=1,['derechos']=1,['desambiguación']=1,
	['editor']=1,  ['editorial']=1, ['enlaces']=1,['históricos']=1,['ilustrador']=1,['imprenta']=1, ['lugar']=1, ['más info']=1,['meta']=1,['noano']=1,['notas']=1, 
	['progreso']=1, ['próximo']=1, ['sección']=1,['sección autor']=1,['sub-titulo']=1,['subsección']=1,['subpágina']=1,['titulo']=1,['traductor']=1,['última muerte']=1,
	['volumen']=1, ['wikcionario']=1,['wikidata']=1,['wikilibros']=1,['wikinoticias']=1,['wikipedia']=1,['wikiquote']=1,['wikispecies']=1,['wikiversidad']=1}
local enlacePagina = mw.title.getCurrentTitle().text
local textoenlace=mw.uri.encode(enlacePagina,QUERY)

local altparams= {['título']='titulo', ['title']='titulo', 
	['subtítulo']='sub-titulo', ['subtitulo']='sub-titulo', ['sub-título']='sub-titulo', ['sub-title']='sub-titulo', ['subtitle']='sub-titulo', 
	['left']='anterior', 
	['right']='próximo', ['siguiente']='próximo',
	['author']='autor', 
	['traducción']='traductor', 
	['año']='ano', 
	['bilingue']='bilingüe',
	['noaño']='noano',
	['nota']='notas',
	['subpagina']='subpágina',
	['seccion']='sección',
	['seccion autor']='sección autor',	['seccion-autor']='sección autor',	['sección-autor']='sección autor'
}
function nav_link(argus, class, arrow, content)
	local span = mw.html.create('span'):addClass(class..'-span')
	span:tag('span'):addClass(class..'-span-arrow')
	if class=='prev' then span:wikitext(arrow .. ' ' .. content) end
	if class=='next' then span:wikitext(content .. ' ' .. arrow) end
	if argus['enlaces'] and mw.ustring.lower(argus['enlaces']) == 'no' then
		span:cssText('display:none')
	end
	return tostring(span)
end
function errorMessage(text)
	-- Función que entrega un mensaje de error formateado como tal
	local html = mw.html.create('div')
	html:addClass('error')
		:wikitext(text)
	categorias=categorias..'[[Categoría:Wikisource:Páginas con errores en la plantilla Encabe]]'
	return tostring(html)
end

local function link(s)
	if s:find("[%[%{%<]") then
		return s
	else
		return '[[Autor:'..s..'|'..s..']]'
	end
end
local function delink(s)
	if not s:match("%[") then
		return s
	end
    local result = s
    
    result = mw.uri.decode(result, "PATH") -- decode percent-encoded entities. Leave underscores and plus signs.
    result = mw.text.decode(result, true) -- decode HTML entities.
  
    -- Remove the colon if the link is using the [[Help:Colon trick]].
    if result:match("%[%[:") then
        result = "[[" .. result:match("%[%[:(.*%]%])")
    end
   
    -- Find the display area of the wikilink
    if result:match("|") then -- Find if we're dealing with a pipecd link.
        result = result:match("%[%[.-%|(.+)%]%]")
        -- Remove new lines from the display of multiline piped links,
        -- where the pipe is before the first new line.
        result = result:gsub("\n", "")
    else     
    	result = result:match("%[%[(.-)%]%]")
    end

    return result
end

function microformato(d, argus)
	local microformato = mw.html.create('div')
			:cssText('display:none')
			:attr('id', 'ws-data')
			:addClass('ws-noexport')
	
-- todo: no captura datos del Índice si tiene otro Wikidata (p.ej. Q88887973)
-- todo: los que no están en  [[Plantilla:Proofreadpage header template]] (lugar, volumen, nivel) no llegan del
--		índice y sólo los captura de Wikidata.
	if d.titulo and d.titulo ~= '' then
		microformato:node( enlaceMicroformato( 'title', d.titulo ) )
		microformato:node( enlaceMicroformato( 'key', d.titulo ) )	--todo: mejorable
	end
	if d.ano and d.ano ~= '' then
        microformato:node( enlaceMicroformato( 'year', d.ano ) )
    end
    if d.autor and d.autor ~= '' then
        microformato:node( enlaceMicroformato( 'author', d.autor ) )
    end
    if d.traductor and d.traductor ~= '' then
        microformato:node( enlaceMicroformato( 'translator', d.traductor ) )
    end
    if d.ilustrador and d.ilustrador ~= '' then
        microformato:node( enlaceMicroformato( 'illustrator', d.ilustrador ) )
    end
    if argus["sección"] and argus["sección"] ~= '' then
        microformato:node( enlaceMicroformato( 'chapter', argus["sección"] ) )
    end
    if d.imprenta and d.imprenta ~= '' then	--ojo: Editorial ~= Editor ~= Imprenta
        microformato:node( enlaceMicroformato( 'publisher', d.imprenta ) )
    end
    if d.lugar and d.lugar ~= '' then
        microformato:node( enlaceMicroformato( 'place', d.lugar ) )
    end
    if d.nivel and d.nivel ~= '' then
        microformato:node( enlaceMicroformato( 'progress', d.nivel ) )
    end
    if d.volumen and d.volumen ~= '' then
        microformato:node( enlaceMicroformato( 'volume', d.volumen ) )
    end
	--todo: pdte. (¿adaptar de [[:ca:Module:Header]]?)
	--if argus.index then
    --    microformato:node( enlaceMicroformato( 'scan', argus.index ) )
    --    if argus.image and mw.ustring.match(argus.image, '^%d+$') ~= nil then
    --        microformato:node( enlaceMicroformato( 'cover', argus.index .. '/' .. argus.image ) )
    --    end
    -- end

	--todo: ¿extraer de listaenlaces? argus.x ~= listaenlaces
	if argus.wikipedia and argus.wikipedia ~= '' then
        microformato:node( enlaceMicroformato( 'wikipedia', argus.wikipedia ) )
    end
    if argus.wikiquote and argus.wikiquote ~= '' then
        microformato:node( enlaceMicroformato( 'wikiquote', argus.wikiquote ) )
    end
    if argus.commonscat and argus.commonscat ~= '' then
        microformato:node( enlaceMicroformato( 'commons', argus.commons ) )
    end

	if argus.notas and argus.notas ~= '' then
        microformato:tag('div')   --no puede ser span
        :addClass('ws-summary')
        :wikitext(argus.notas)	
    end
    
    return tostring(microformato)
end
function enlaceMicroformato(param, valor)
	if valor and valor ~= '' then
		return mw.html.create('span')
        :addClass('ws-' .. param)	--ws-author, ws-title, etc.
        :wikitext(delink(valor))	--todo: no OK si >1, p.ej. autores de [[Glosario de la Lengua Atacameña]]
	else 
		return ''
	end
end
-- Elije entre info local o Wikidata
function resolverWikidataNivel(argus, parametro)
	local ws = argus[parametro]	--nivel
	local badges = require("Module:Wikidata").badge{args={qid=argus['wikidata'], ws=ws, indicator=true}}
	return mw.getCurrentFrame():preprocess(badges)
end
function resolverWikidata(argus, parametro, PID)
	local ws = argus[parametro]
	if not ws or ws == '' then
    	ws = Wikidata.claim{item=argus['wikidata'], property=PID, lang="es", list=false}
	end
	if ws and ws~= '' then return ws end
end
function resolverWikidataPersona(argus, parametro, PID)
	local ws = argus[parametro]
	
	if ws == 'no' then return end
	
	if ws and ws~= '' then
		local split = mw.text.split(ws, '[/,]')
		local i = #split
    	ws = ''
    	for _,v in ipairs(split) do
			i = i-1
			if ws == 'Wikisource' then
				ws = '[[Ayuda:Directrices para traducciones|Wikisource]]'
			else
				ws = ws..link(v)
			end
			if i > 0 then
				ws = ws..', '
			end
		end
		
	elseif not ws or ws == '' then
    	ws = Wikidata.claim{item=argus['wikidata'], property=PID, lang="es", list=true}
	end
	
	if ws and ws~= '' then return ws end
	
end
function consolidado(argus)
	local data = {}
    local props = {
    	titulo = {'titulo', 'P1476'},
    	subtitulo = {'sub-titulo', 'P1680'},
    	ano = {'ano', 'P577'},
		lugar = {'lugar', 'P291'},
		imprenta = {'imprenta', 'P872'},
		volumen = {'volumen', 'P478'},
    	autor = {'autor','P50', persona = true},
    	traductor = {'traductor', 'P655', persona = true},
    	ilustrador = {'ilustrador', 'P110', persona = true},
    	nivel = {'progreso', nivel=true},
    }
	for k, v in pairs(props) do
		if v.nivel then
			data[k] = resolverWikidataNivel(argus, v[1])
		elseif v.persona then
			data[k] = resolverWikidataPersona(argus, v[1], v[2])
		else
			data[k] = resolverWikidata(argus, v[1], v[2])
		end
	end
	return data
end
function p.encabe( frame ) 
    local titulo = mw.title.getCurrentTitle()
    local html = mw.html.create()
    local argus = Args.getArgs(frame)
	argus = Args.alias(argus, altparams)
	local essub = titulo.isSubpage
    if argus['subpágina'] == 'no' then
		essub = false
    end
    
	-- QID real prevalece sobre el importado desde el índice (importante en subdivisiones)
    if QID and QID ~= '' then
	    argus['wikidata'] = QID or argus['wikidata'] or ''
    end
	-- obtener todos los datos
	local d = consolidado(argus)
	--variables matemática derechos de autor
	local anosmuerte
	local anospub
	if d.ano and tonumber(d.ano) ~= nil  then
		anospub = tonumber(lang:formatDate('Y')) - tonumber(d.ano)
	end
	if argus['última muerte'] and tonumber(argus['última muerte']) ~= nil then
		anosmuerte = tonumber(lang:formatDate('Y')) - tonumber(argus['última muerte'])
	end
	
	-- estructura HTML
    local divgrande = html:tag('div'):attr('id','headertemplate'):addClass('noprint ws-noexport') -- div principal que contiene al resto
	local anterior = divgrande:tag('div'):attr('id','headerprevious')
	local medio = divgrande:tag('div'):addClass('middle-div')
	local proximo = divgrande:tag('div'):attr('id','headernext')
	----- enlaces de navegación
	if argus['anterior'] and argus['anterior'] ~= '' then
		anterior:wikitext(nav_link(argus, 'prev', '← ', argus['anterior']))
	end
    if argus['próximo'] and argus['próximo'] ~= '' then
		proximo:wikitext(nav_link(argus, 'next', ' →', argus['próximo']))
	end
    
    -- datos bibliográficos
    if d.titulo then
    	medio:wikitext("'''''".. d.titulo .."'''''")
    	if d.subtitulo then
    		medio:wikitext(': '..'<span style="font-size:83%;">'.. d.subtitulo ..'</span>')	
    	end
    	if d.ano and not argus['noano'] then
    		medio:wikitext(' ('.. d.ano ..')')
    		if tonumber(d.ano) ~= nil then
	    		categorias = categorias..'[[Categoría:P'.. d.ano ..']]'
	    	end
    	end
		medio:wikitext('<br>')
    end
    
	if d.autor then
		medio:wikitext('de '.. d.autor ..'<br>')
	end
    if d.traductor then
    	for _,v in ipairs(mw.text.split(d.traductor, '[/,]')) do
			if (delink(v) == 'Anónimo')  or  (delink(v) == 'valor desconocido') then
				categorias = categorias..'[[Categoría:Traducciones de autor anónimo]]'
			else
				local cadena = d.traductor
				cadena = cadena:gsub("] y ", "], ")
				for nombre in cadena:gmatch("([^,]+)") do
    				categorias = categorias..'[[Categoría:Traducciones de '..delink(nombre):match("^%s*(.-)%s*$") ..']]'
				end
			end
		end
    	medio:wikitext('traducción de '..d.traductor..'<br>')
    end
    
	if d.ilustrador then
    	for _,v in ipairs(mw.text.split(d.ilustrador, '[/,]')) do
			if (delink(v) == 'Anónimo')  or  (delink(v) == 'valor desconocido') then
				categorias = categorias..'[[Categoría:Ilustraciones de autor anónimo]]'
			else
				local cadena = d.ilustrador
				cadena = cadena:gsub("] y ", "], ")
				for nombre in cadena:gmatch("([^,]+)") do
    				categorias = categorias..'[[Categoría:Ilustraciones de '..delink(nombre):match("^%s*(.-)%s*$") ..']]'
				end
			end
		end
		medio:wikitext('ilustración de '.. d.ilustrador ..'<br>')
	end
	
    if argus['más info'] then
    	medio:wikitext(argus['más info']..'<br>')
    end

    if argus['sección'] then
    	medio:wikitext("''"..argus['sección'].."''")
    	if argus['sección autor'] then
    		medio:wikitext(' de '..resolverWikidataPersona(argus, 'sección autor'))
    	end
   		if argus['subsección'] then
   			medio:tag('span'):cssText('font-size: 83%;'):wikitext('<br>'..argus['subsección'])
   		end
    end
    
	--    ENLACES A PROYECTOS HERMANOS
    inferior = medio:tag('div'):addClass('noprint plainlinks lower-div')
	listaenlaces = Enlaces.all(argus)
   
    --matematica y manejo derechos de autor
    if argus['derechos'] then
    	listaenlaces[1] = {['text']   = argus.derechos,
					['image']  = 'PD-icon.svg',
					['prefix'] = ':Wikisource:Duración de derechos de autor por país#',
					['title']  = argus.derechos}
				
		if argus['última muerte'] == 'seudónimo' then
    		numero = math.floor((anospub - 1)/10)
    		if numero > 10 then numero = 10 end
    		listaenlaces[2] = {['image']  = nil,
					['text']   = tostring(numero*10)..' p.a.p. o menos',
					['prefix'] = ':Wikisource:Duración de derechos de autor por país#',
					['title']  = tostring(numero*10)..' p.a.p.'}
    		categorias = categorias..'[[Categoría:'..tostring(numero*10)..' p.a.p.]]'
    	elseif argus['última muerte'] then
			numero = math.floor((anosmuerte - 1)/10)
    		if numero > 4 then --a partir de 50 p.m.a.
    			if numero > 10 then numero = 10 end
    			listaenlaces[2] = {['image']  = nil,
					['text']   = tostring(numero*10)..' p.m.a. o menos',
					['prefix'] = ':Wikisource:Duración de derechos de autor por país#',
					['title']  = tostring(numero*10)..' p.m.a.'}
    			categorias = categorias..'[[Categoría:'..tostring(numero*10)..' p.m.a.]]'
    		end
    	end
    	local cadena = argus.derechos:gsub(" y ", ", ")

		-- Usar string.gmatch para separar por comas y procesar directamente
		for nombre in cadena:gmatch("([^,]+)") do
			categorias = categorias..'[[Categoría:Publicado en '.. nombre:match("^%s*(.-)%s*$") ..']]'
		end
    	--categorias = categorias..'[[Categoría:Publicado en '.. argus.derechos ..']]'
	end
	
	-- inserta enlaces
	inferior:wikitext(Enlaces.formattedlinks(listaenlaces))
	
	if argus['bilingüe'] and argus['bilingüe'] ~= '' then
		inferior:wikitext('['..titulo:fullUrl({['match']=argus['bilingüe']})..' ver texto bilingüe]')
	end
	
	--Enlaces de descarga
	if not essub then
		local LinkExport='https://ws-export.wmcloud.org/?lang=es&page='..textoenlace..'&format='
		local w = "<div style=\"font-size:80%\">Descargar como &nbsp;"
		w = w .. "[[Archivo:EPUB silk icon.svg|12px|link="..LinkExport.."epub|Descargar en formato ePub]]&nbsp;"
		w = w .. "[[Archivo:Document-pdf.svg|15px|link="..LinkExport.."pdf|Descargar en formato PDF]]&nbsp;"
		w = w .. "[[Archivo:Mobi_icon.svg|22px|link="..LinkExport.."mobi|Descargar en formato mobi]]</div>"
		inferior:wikitext(w)
	end 

	if argus['notas'] and argus['notas'] ~= '' then
		html:tag('div'):addClass('notes noprint ws-noexport'):wikitext("'''Nota:''' "..argus['notas']):tag('hr')
	end
	
	--categorías automáticas
	if not essub then
		categorias = categorias..'[[Categoría:ES-'..Str.CaracterParaOrdenar(titulo.rootText)..']]'
	else
		categorias = '[[Categoría:'..titulo.rootText..']]'
		html:wikitext('__EXPECTED_UNCONNECTED_PAGE__')
	end
	
    for k,v in pairs(argus) do
		if params[k] or altparams[k] then
			if params[k] == 0 then
				categorias = categorias..'[[Categoría:Wikisource:Páginas que usan parámetros obsoletos en la plantilla Encabe]]' --añade categoría de seguimiento a parámetros obsoletos (declarados arriba)
			end
		else
			html:wikitext(errorMessage('Error: parámetro '..k..' no reconocido'))
			categorias=categorias..'[[Categoría:Wikisource:Páginas que usan parámetros no reconocidos en la plantilla Encabe]]'
		end
	end
	if titulo.namespace ~= 0 then --solo categorías en el espacio principal
		categorias = ''	
	end
	
	html:wikitext(categorias)

	html:wikitext(microformato(d, argus))

    return tostring(html)

end
return p