Módulo:Wikidata/Formatos
Ir a la navegación
Ir a la búsqueda
Uso
Tipos de datos de la plantilla propiedad
En este módulo se definen algunos de los tipos de datos más utilizados en la plantilla {{propiedad}}
. La utilización es sencilla:
{{propiedad|propiedad|texto alternativo|tipo de datoPlantilla:=tipo de dato|parámetros opcionales}}
- propiedad: propiedad de Wikidata, por ejemplo P18.
- texto alternativo: si está informado no se obtendrán los datos de Wikidata.
- tipo de dato: una función en Lua que acepta como argumentos las siguientes tablas:
- valor: datos obtenidos de Wikidata para la propiedad. El único parámetro obligatorio
- opciones: argumentos con los que se accede a la plantilla propiedad
- marco o frame:
- calificativos: calificativos de la propiedad en Wikidata
- parámetros opcionales: parámetros opcionales documentados en la plantilla
{{propiedad}}
o en el tipo de dato específico
Véase también
- Módulo:Wikidata/Formato premio para premios
local p = {} local es = mw.language.new('es') local moduloTablas = require('Módulo:Tablas') local elementoTabla = moduloTablas.elemento local enTabla = moduloTablas.en local insertarEnTabla = moduloTablas.insertar local moduloWikidata = require('Módulo:Wikidata') local getPropiedadWikidata = moduloWikidata.getPropiedad local formatoDatoWikidata = moduloWikidata.formatoDato local enlazarURL = require('Módulo:URL').enlazar function p.formatCoor(value) local cadenacoor = value return marco:preprocess('{{coord|' .. cadenacoor[tostring('latitude')] ..'|'.. cadenacoor[tostring('longitude')] .. '|format=dms}}') end -- Funciones para entidades de Wikidata function p.formatoGentilicio(valor, opciones, frame) local enlacePais, etiquetaPais, idEntidadPais = p.obtenerDatos(valor) local gentilicio if etiquetaPais then gentilicio = frame:preprocess('{{gentilicio|'.. etiquetaPais .. '|fs}}') if not gentilicio or gentilicio == '' then gentilicio = etiquetaPais end end return p.enlazar(enlacePais, gentilicio, idEntidadPais, opciones) end function plural(texto) if texto:match('^.*[aeiou]$') then -- 'hombre' => 'hombres', 'metro' => 'metros' texto = texto .. 's' elseif texto:match('^.*[^s]$') then -- 'mujer' => 'mujeres', 'pascal' => 'pascales', (*) 'siemens' => 'siemens' texto = texto .. 'es' end return texto end function p.formatoUnidad(valor, opciones) cantidad = mw.ustring.gsub(valor.value['amount'], '+','') unidad = mw.wikibase.label(mw.ustring.gsub(valor.value['unit'], '^.-/(Q%d+)$', '%1')) if unidad and tonumber(cantidad) > 1 then textoUnidad = mw.ustring.gsub(unidad, '(%S+)', plural) -- correcciones específicas de los plurales: local correcciones = { ['caballos des vapores'] = 'caballos de vapor', ['galónes'] = 'galones', ['años luzes'] = 'años luz', ['párseces'] = 'pársecs', ['metros cúbicos pores segundos'] = 'metros cúbicos por segundo', } textoUnidad = correcciones[textoUnidad] or textoUnidad elseif unidad then textoUnidad = unidad end if not unidad or (opciones['formatoUnidad'] and opciones['formatoUnidad'] == 'número') then return tonumber(cantidad) elseif unidad and opciones['formatoUnidad'] and opciones['formatoUnidad'] == 'minutos' and unidad == 'segundo' then local segundos = tostring(tonumber(cantidad)%60) if mw.ustring.len(segundos) == 1 then segundos = '0' .. segundos end return math.floor(tonumber(cantidad)/60) .. ':' .. segundos .. ' ' .. 'minutos' else return p.formatoNumero(cantidad) .. ((textoUnidad and ' ' .. textoUnidad) or '') end end function p.formatoNumero(valor, opciones) if valor['amount'] then valor = mw.ustring.gsub(valor['amount'], '+', '') end if not tonumber(valor) then return valor end local formato = valor while true do formato, k = string.gsub(formato, "^(-?%d+)(%d%d%d)", '%1 %2') if (k==0) then break end end return formato end -- :: Funciones experimentales -- Función para obtener el wikitexto a partir de una entidad de Wikidata perteneciente a una unidad -- @param string val la entidad de Wikidata (con URL) -- @return string el wikitexto, de encontrarse el valor correspondiente function p.getUnit(val) local vals = mw.loadData('Módulo:Wikidata/unidades/datos') q = string.sub(val, 32) return vals[q] end -- Alternativa a formatoUnidad() -- @param table objeto el objeto datavalue -- @param table opciones una lista de opciones. Las opciones aceptadas son: -- * string separador un separador (espacio duro por defecto) -- * bool izquierda si colocar la unidad a a izquierda (por defecto va a la derecha) function p.formatoUnidad2(objecto, opciones) local Valor = elementoTabla(objecto, 'value') local Tipo = elementoTabla(objecto, 'type') if Tipo == 'quantity' then if not opciones then opciones = {} end local Separador = opciones['separador'] or ' ' local Izquierda = opciones['izquierda'] local Unidad = (function() local Unidad = elementoTabla(Valor, 'unit') if Unidad then return p.getUnit(Unidad .. '-plural') or p.getUnit(Unidad) end end)() if Unidad then Valor = p.formatoNumero2(string.sub(elementoTabla(Valor, 'amount'), 2)) if Izquierda then return Unidad .. Separador .. Valor end return Valor .. Separador .. Unidad end end return Valor end -- Función formatoNumero() alternativa. -- Envoltura para mw.language:formatNum(), -- que permite devolver el valor entregado en lugar de nil -- @param num el número, ya sea 'number' o 'string' -- @return number el valor, en formato numérico function p.formatoNumero2(valor, opciones) if not tonumber(valor) then return valor end if not opciones then opciones = {} end local Decimales = tonumber(opciones['decimales']) if opciones['noCommafy'] then noCommafy = true end if tonumber(Decimales) then return es:formatNum(tonumber(math.floor(valor * (10^Decimales)) / (10^Decimales)), noCommafy) end return es:formatNum(tonumber(valor, noCommafy)) end function p.formatoCargo(valor, opciones, frame, calificativos) local enlaceCargo, etiquetaCargo, idEntidadCargo = p.obtenerDatos(valor) local cargoEnlazado = p.enlazar(enlaceCargo, etiquetaCargo, idEntidadCargo, opciones) if not cargoEnlazado then return end -- De local enlaceDe, etiquetaDe, idEntidadDe = p.obtenerDatos(elementoTabla(calificativos,'P642',1,'datavalue','value')) local deEnlazado = p.enlazar(enlaceDe, etiquetaDe, idEntidadDe, opciones) if deEnlazado then cargoEnlazado = cargoEnlazado .. ' de ' .. deEnlazado end -- Distrito electoral local enlaceDistritoElectoral, etiquetaDistritoElectoral, idEntidadDistritoElectoral = p.obtenerDatos(elementoTabla(calificativos,'P768',1,'datavalue','value')) local DistritoElectoralEnlazado = p.enlazar(enlaceDistritoElectoral, etiquetaDistritoElectoral, idEntidadDistritoElectoral, opciones) if DistritoElectoralEnlazado then cargoEnlazado = cargoEnlazado .. ' por ' .. DistritoElectoralEnlazado end -- Empleador local enlaceEmpleador, etiquetaEmpleador, idEntidadEmpleador = p.obtenerDatos(elementoTabla(calificativos,'P108',1,'datavalue','value')) local EmpleadorEnlazado = p.enlazar(enlaceEmpleador, etiquetaEmpleador, idEntidadEmpleador, opciones) if EmpleadorEnlazado then cargoEnlazado = cargoEnlazado .. ' de ' .. EmpleadorEnlazado end local periodo = p.formatoPeriodo(calificativos, {}) if periodo then return cargoEnlazado .. ' <small>(' .. periodo .. ')</small>' else return cargoEnlazado end end -- Formatos de calificativos function p.formatoPeriodo(valor, opciones) if not valor then return end local anyoInicio, anyoFin local fechaInicio, fechaFin local opcionesFecha= {['formatoTexto']='mayúscula', ['formatoFecha'] = 'año', ['enlace']='no'} local fechasInicio = valor['P580'] local fechasFin = valor['P582'] local iFechaInicio = 1 local iFechaFin = 1 if not fechasInicio and not fechasFin then return end local periodos = {} if fechasInicio and fechasInicio[1] then --if true then return require('Módulo:Tablas').tostring(fechasInicio[1]) end anyoInicio = formatoDatoWikidata(fechasInicio[1],opcionesFecha , {}) fechaInicio= anyoInicio -- de momento end if fechasFin and fechasFin[1] then anyoFin = formatoDatoWikidata(fechasFin[1], opcionesFecha, {}) fechaFin = anyoFin -- de momento end while fechaInicio or fechaFin do -- Por cada periodo if fechaInicio and fechaFin and tonumber(fechaInicio) and tonumber(fechaFin) and (tonumber(fechaInicio) <= tonumber(fechaFin)) then if anyoInicio == anyoFin then table.insert(periodos, anyoInicio) else table.insert(periodos, anyoInicio .. '-' .. anyoFin) end iFechaInicio = iFechaInicio + 1 iFechaFin = iFechaFin + 1 if fechasInicio[iFechaInicio] then anyoInicio = formatoDatoWikidata(fechasInicio[iFechaInicio],opcionesFecha , {}) fechaInicio= anyoInicio -- de momento else anyoInicio = nil fechaInicio= nil end if fechasFin[iFechaFin] then anyoFin = formatoDatoWikidata(fechasFin[iFechaFin],opcionesFecha , {}) fechaFin= anyoFin -- de momento else anyoFin = nil fechaFin= nil end elseif anyoInicio then table.insert(periodos, 'desde ' .. anyoInicio) iFechaInicio = iFechaInicio + 1 if fechasInicio[iFechaInicio] then anyoInicio = formatoDatoWikidata(fechasInicio[iFechaInicio],opcionesFecha , {}) fechaInicio= anyoInicio -- de momento else anyoInicio = nil fechaInicio= nil end elseif anyoFin then table.insert(periodos, 'hasta ' .. anyoFin) iFechaFin = iFechaFin + 1 if fechasFin[iFechaFin] then anyoFin = formatoDatoWikidata(fechasFin[iFechaFin],opcionesFecha , {}) fechaFin= anyoFin -- de momento else anyoFin = nil fechaFin= nil end end end return table.concat(periodos, ', ') end -- Funciones internas -- Las siguientes funciones hacen prácticamente lo mismo que la función -- formatoIdEntidad del módulo Wikidata. -- p.obtenerDatos obtiene los datos de la entidad y p.enlazar los formatea. function p.obtenerDatos(valor) if valor and valor['numeric-id'] then local idEntidad = 'Q' .. valor['numeric-id'] local etiqueta = mw.wikibase.label( idEntidad ) local enlace = mw.wikibase.sitelink( idEntidad ) return enlace, etiqueta, idEntidad end end function p.enlazarEnOtroIdioma(enlace, etiqueta, idioma) local categoria = '[[Categoría:Wikipedia:Páginas con propiedades de Wikidata con etiqueta en otro idioma]]' if enlace and etiqueta then return etiqueta .. ' <small>([[:' .. idioma .. ':' .. enlace .. '|' .. idioma .. ']])</small>' .. categoria elseif etiqueta then return etiqueta .. ' <small>(' .. idioma .. ')</small>' .. categoria elseif enlace then return enlace .. ' <small>([[:' .. idioma .. ':' .. enlace .. '|' .. idioma .. ']])</small>' .. categoria end end local yaEnlazado = {} function p.enlazar(enlace, etiqueta, idEntidad, opciones) if not enlace and not etiqueta and not idEntidad then return end if opciones then -- Opciones de las etiquetas if opciones.etiqueta and opciones.etiqueta ~= 'null' then -- Por averiguar dónde se usa. etiqueta = opciones.etiqueta end --if opciones['espacioDeNombres'] then enlace = opciones['espacioDeNombres'] .. ':' .. enlace end -- Convertir el primer carácter a mayúscula en su caso if etiqueta and opciones['mayúscula'] == 'sí' then etiqueta = es:ucfirst(etiqueta) end -- Opciones del enlace if opciones['enlace'] == 'no' then -- No p.enlazar enlace = nil elseif opciones['debeExistir'] == 'sí' then -- No devolver nada si no está informado el artículo de Wikipedia if not enlace then return end elseif opciones['enlace'] == 'sí' then if not enlace and etiqueta and not require('Módulo:Páginas').existe(etiqueta) then -- Tomar como enlace la etiqueta si no existe el correspondiente artículo enlace = etiqueta end end end -- No enlazar varias veces lo mismo if enlace and yaEnlazado[enlace] then enlace = nil end -- Según esté informada la etiqueta o el enlace local resultado if etiqueta and enlace and etiqueta ~= enlace then --Ambos si no son iguales resultado = '[[' .. enlace .. '|' .. etiqueta .. ']]' yaEnlazado[enlace] = true elseif enlace then -- Solo el enlace o ambps y son iguales resultado = '[[' .. enlace .. ']]' yaEnlazado[enlace] = true elseif etiqueta then -- Solo la etiqueta resultado = etiqueta elseif idEntidad then -- Solo la entidad -- Obtener la etiqueta y el enlace de Wikidata de la Wikipedia inglesa, francesa o alemana local entidad=mw.wikibase.getEntityObject(idEntidad) --if true then return require('Módulo:Tablas').tostring(entidad) end if entidad then local idioma for k, idioma in pairs({'en', 'fr', 'it', 'de'}) do etiqueta = elementoTabla(entidad, 'labels', idioma, 'value') enlace = elementoTabla(entidad, 'sitelinks', idioma .. 'wiki', 'title') if etiqueta or enlace then resultado = p.enlazarEnOtroIdioma(enlace, etiqueta, idioma) break end end end if not resultado then return '[[:d:'.. idEntidad .. '|sin etiquetar]]' .. '[[Categoría:Wikipedia:Páginas con propiedades de Wikidata sin etiqueta]]' end end -- Añadir cursivas if opciones and opciones.cursivas == 'sí' then resultado = "''" .. resultado .. "''" end return resultado end function p.formatId( value, options ) local wikidata = require('Módulo:Wikidata') local id = 'Q'.. value['numeric-id'] local opciones = {separador = '<br>',propiedad = options.propiedadValor, uno = 'sí', entityId = id, formatoTexto = 'mayúscula'} return wikidata.getPropiedad(opciones) end function p.formatBandera2( value, options ) local bandera = require('Módulo:Bandera') local id = 'Q'.. value['numeric-id'] local label = mw.wikibase.label( 'Q' .. value['numeric-id'] ) or '' local tipo = mw.ustring.gsub(label,'(%D+)%sde%s%D+','%1') if options.cortar and options.cortar ~= '' then coincidencia = mw.ustring.find( es:lc(options.cortar), es:lc(tipo), plain ) end if coincidencia then nombre = mw.ustring.gsub(label,'%D+%sde%s(%D+)','%1') elseif label and label ~= '' then nombre = label end return bandera.banderaLua(id, '20px', '', nombre) end function p.formatFicha( value, options ) local ficha = require('Módulo:Ficha') local opciones = {propiedadValor='P31'} local etiqueta = p.formatId( value, opciones) options.cortar = etiqueta local parametros = { child = 'si', estiloetiqueta1 = 'border:0;font-weight:100;padding:0px 7px', estilodatos1 = 'border:0;font-weight:100;padding:0px 7px 0px 2px', etiqueta1='• '.. es:ucfirst(etiqueta), datos1 = p.formatBandera2(value, options)} return ficha.infobox(parametros) end function p.formatoId ( value, options ) return value['numeric-id'] and 'Q' .. value['numeric-id'] end --***************************************************************************** -- Funciones para un elemento/entidad de Wikidata --***************************************************************************** function p.formatoObraAutor(valor, opciones, frame, calificativos) local idObra = 'Q' .. valor['numeric-id'] local entidadObra = mw.wikibase.getEntityObject(idObra) local enlaceObra = elementoTabla(entidadObra,'sitelinks','eswiki','title') local etiquetaObra = elementoTabla(entidadObra,'labels','es','value') local tituloObraEnlazado = p.enlazar(enlaceObra, etiquetaObra, idObra, opciones) local declaracionAutores = elementoTabla(entidadObra, 'claims', 'P50') if declaracionAutores then local autores = getPropiedadWikidata({['propiedad']='P50'}, entidadObra.claims['P50']) if autores then return "''" .. tituloObraEnlazado .. "'' de " .. autores end end local declaracionCreadores = elementoTabla(entidadObra, 'claims', 'P170') if declaracionCreadores then local creadores = getPropiedadWikidata({['propiedad']='P170'}, entidadObra.claims['P170']) if creadores then return "''" .. tituloObraEnlazado .. "'' de " .. creadores end end return "''" .. tituloObraEnlazado .. "''" end function p.formatoObraAnyo(valor, opciones, frame, calificativos) local idObra = 'Q' .. valor['numeric-id'] local entidadObra = mw.wikibase.getEntityObject(idObra) local enlaceObra = elementoTabla(entidadObra,'sitelinks','eswiki','title') local etiquetaObra = elementoTabla(entidadObra,'labels','es','value') local tituloObraEnlazado = p.enlazar(enlaceObra, etiquetaObra, idObra, opciones) local declaracionFechaPublicacion = elementoTabla(entidadObra, 'claims', 'P577') if declaracionFechaPublicacion then local anyoPublicacion = getPropiedadWikidata({['propiedad']='P577', ['formatoFecha']='año', ['rangoMayor']='sí', ['enlace']='no', ['uno']='sí'}, declaracionFechaPublicacion) if anyoPublicacion then return "''" .. tituloObraEnlazado .. "'' (" .. anyoPublicacion .. ")" end end return "''" .. tituloObraEnlazado .. "''" end function p.formatoObraTituloOriginalAnyo(valor, opciones, frame, calificativos) local idObra = 'Q' .. valor['numeric-id'] local entidadObra = mw.wikibase.getEntityObject(idObra) local enlaceObra = elementoTabla(entidadObra,'sitelinks','eswiki','title') local etiquetaObra = elementoTabla(entidadObra,'labels','es','value') local tituloObraEnlazado = p.enlazar(enlaceObra, etiquetaObra, idObra, opciones) local tituloOriginal = elementoTabla(entidadObra, 'claims', 'P1476',1,'mainsnak','datavalue','value','text') local declaracionFechaPublicacion = elementoTabla(entidadObra, 'claims', 'P577') local anyoPublicacion if declaracionFechaPublicacion then anyoPublicacion = getPropiedadWikidata({['propiedad']='P577', ['formatoFecha']='año', ['enlace']='no'}, declaracionFechaPublicacion) end if tituloOriginal and anyoPublicacion then return "''" .. tituloObraEnlazado .. "'' (''" .. tituloOriginal .. "'', " .. anyoPublicacion .. ")" elseif tituloOriginal then return "''" .. tituloObraEnlazado .. "'' (''" .. tituloOriginal .. "'')" elseif anyoPublicacion then return "''" .. tituloObraEnlazado .. "'' (" .. anyoPublicacion .. ")" else return "''" .. tituloObraEnlazado .. "''" end end local decadaAnterior function p.formatoPersonaPremiadaPor(valor, opciones, frame, calificativos) local enlacePersona, etiquetaPersona, idEntidadPersona = p.obtenerDatos(valor) local personaEnlazada = p.enlazar(enlacePersona, etiquetaPersona, idEntidadPersona, {['enlace'] = 'sí'}) local fecha, decada, decadaFormateada local enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1, obraPremiadaEnlazada1 local enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2, obraPremiadaEnlazada2 local obraPremiadaEnlazada local opcionesFecha= {['formatoTexto']='mayúscula', ['formatoFecha'] = 'año', ['enlace']='no'} if calificativos then fecha = formatoDatoWikidata(elementoTabla(calificativos,'P585',1), opcionesFecha , {}) -- Primera fecha enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1 = p.obtenerDatos(elementoTabla(calificativos,'P1686',1,'datavalue','value'))-- Premiado por enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2 = p.obtenerDatos(elementoTabla(calificativos,'P1686',2,'datavalue','value'))-- Premiado por obraPremiadaEnlazada1 = p.enlazar(enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1, {['enlace'] = 'sí'}) obraPremiadaEnlazada2 = p.enlazar(enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2, {['enlace'] = 'sí'}) obraPremiadaEnlazada = (obraPremiadaEnlazada1 and obraPremiadaEnlazada2 and (obraPremiadaEnlazada1 .. ' / ' .. obraPremiadaEnlazada2)) or obraPremiadaEnlazada1 or obraPremiadaEnlazada2 end decadaFormateada = '' if fecha then decada = tostring(fecha):sub(1,3) if decada ~= decadaAnterior then decadaAnterior = decada decadaFormateada = "</ul>'''" .. fecha .. "-" .. decada .. "9'''\n<ul><li>" end end return decadaFormateada .. (obraPremiadaEnlazada and ("''" .. obraPremiadaEnlazada .. "''") or '') .. (obraPremiadaEnlazada and personaEnlazada and ' de ' or '') .. personaEnlazada .. (fecha and ' (' .. fecha .. ')' or '') end function p.formatoPersonaPremiadaPor2(valor, opciones, frame, calificativos) local enlacePersona, etiquetaPersona, idEntidadPersona = p.obtenerDatos(valor) local personaEnlazada = p.enlazar(enlacePersona, etiquetaPersona, idEntidadPersona, {['enlace'] = 'sí'}) local fecha, decada, decadaFormateada local enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1, obraPremiadaEnlazada1 local enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2, obraPremiadaEnlazada2 local obraPremiadaEnlazada local opcionesFecha= {['formatoTexto']='mayúscula', ['formatoFecha'] = 'año', ['enlace']='no'} if calificativos then fecha = formatoDatoWikidata(elementoTabla(calificativos,'P585',1), opcionesFecha , {}) -- Primera fecha enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1 = p.obtenerDatos(elementoTabla(calificativos,'P1686',1,'datavalue','value'))-- Premiado por enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2 = p.obtenerDatos(elementoTabla(calificativos,'P1686',2,'datavalue','value'))-- Premiado por obraPremiadaEnlazada1 = p.enlazar(enlaceObraPremiada1, etiquetaObraPremiada1, idEntidadObraPremiada1, {['enlace'] = 'sí'}) obraPremiadaEnlazada2 = p.enlazar(enlaceObraPremiada2, etiquetaObraPremiada2, idEntidadObraPremiada2, {['enlace'] = 'sí'}) obraPremiadaEnlazada = (obraPremiadaEnlazada1 and obraPremiadaEnlazada2 and (obraPremiadaEnlazada1 .. ' / ' .. obraPremiadaEnlazada2)) or obraPremiadaEnlazada1 or obraPremiadaEnlazada2 end return '<td>' .. fecha .. '</td><td>' .. (obraPremiadaEnlazada and ("''" .. obraPremiadaEnlazada .. "''") or '') .. '</td><td>' .. (personaEnlazada or '') .. '</td>' end --***************************************************************************** -- Funciones para los tipos de dato URL --***************************************************************************** function p.formatoURL(valor, opciones, marco) return enlazarURL(valor) end function p.formatoTwitter(valor, opciones, marco) return '[https://twitter.com/' .. valor .. ' ' .. valor .. ']' end function p.formatoFacebook(valor, opciones, marco) return '[https://www.facebook.com/' .. valor .. ' ' .. valor .. ']' end --***************************************************************************** -- Alias de formatos para utilizar en la plantilla propiedad --***************************************************************************** p['bandera'] = p['formatBandera'] p['cargo'] = p['formatoCargo'] p['gentilicio'] = p['formatoGentilicio'] p['personaPremiadaPor'] = p['formatoPersonaPremiadaPor'] --p['premio'] = p['formatoPremio'] p['facebook'] = p['formatoFacebook'] p['twitter'] = p['formatoTwitter'] p['url'] = p['formatoURL'] return p