Wikipedia:Traductor de referencias/código

De Wikipedia, la enciclopedia libre

El traductor está escrito en Python, bajo la licencia CC-BY-SA. Consta de dos módulos, un cgi que se encarga de presentar la página web y controlarla, mientras que otro script se encarga del proceso.

tradrefs.cgi[editar]

#!/usr/bin/python
#coding: utf-8

# Traductor de plantillas de referencia.
# Autor: Pedro Sánchez
# Licencia: Creative Commons By Attribution Share-Alike

import cgi
from traductor import *

print "Content-Type: text/html\n\n"
form = cgi.FieldStorage()   
if "source" not in form:
	fuente="pega aquí la plantilla original"
	trad=""
	checked=""
else:
	if "extended" not in form:  
		compacto=True
		checked=""
	else:
		if form["extended"].value == "1":
			compacto = False
			checked='checked="checked"'
		else:
			compacto=True
			checked=''
	fuente=form["source"].value
	trad=TRADUCE(fuente, compacto)
bar= {"source":fuente, "result":trad, "checked":checked}

foo='''
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="es"><head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type"><title>Traductor de plantillas</title><style type="text/css">
p {
  font-size: medium;
}
#send {
  font-family: Arial,Helvetica,sans-serif;
  font-size: large;
}
body {
  font-family: Arimo,Helvetica,Arial,sans-serif;
}

</style></head><body>
<h1>Traductor de referencias</h1>
<form method="post" action="tradrefs.cgi" enctype="application/x-www-form-urlencoded" name="plantitraductor">
  <table style="text-align: left; width: 100%%;" border="0" cellpadding="2" cellspacing="2">
    <tbody>
      <tr>
        <td style="vertical-align: top;">
        <h3>Original</h3>
        </td>
        <td style="vertical-align: top;">
        <h3>Resultado</h3>
        </td>
      </tr>
      <tr>
        <td style="vertical-align: top; width: 1px;"><textarea cols="40" rows="20" name="source">%(source)s</textarea><br>
        </td>
        <td style="vertical-align: top;"><textarea cols="60" rows="20" name="result">%(result)s</textarea><br>
        </td>
      </tr>
      <tr>
        <td style="vertical-align: top;">
	<input name="extended" value="1" type="checkbox" %(checked)s>Extendido<br>
	<input value="Traduce" name="envia" type="submit">
</td>
        <td style="vertical-align: top;">Plantillas reconocidas<br>
        <ul>
          <li>Cite book → Cita libro</li>
          <li>Cite web → Cita web</li>
        </ul><a href="http://es.wikipedia.org/wiki/Wikipedia:Traductor_de_referencias" target="_blank">Documentación y solicitud de nuevas plantillas.</a><br>

        <a href="http://es.wikipedia.org/w/index.php?title=Wikipedia_Talk:Traductor_de_referencias&amp;action=edit&amp;section=new" target="_blank">Comentarios</a><br>
        <br>
<span style="font-weight: bold;">¡No olvides revisar
manualmente el resultado!</span><br>
        </td>
      </tr>
    </tbody>
  </table>
  <br>
  <small>Autor:<a href="http://es.wikipedia.org/w/index.php?title=User talk:Magister_Mathematicae&amp;action=edit&amp;section=new" rel="me" target="_blank"> Magister Mathematicae</a></small><br>
</form>

</body></html>
'''

print foo % bar

traductor.py[editar]

#!/usr/bin/python
#coding: utf-8
import re

#source='''
#{{Cite book 
#| edition = 2 
#| publisher = [[Dover Publications]] 
#| last = Neugebauer 
#| first = Otto 
#| author-link = Otto E. Neugebauer | title =
# The Exact Sciences in Antiquity | origyear = 1957 | year = 1969 | isbn = 978-048622332-2 | url = http://books.google.com/?id=JVhTtVA2zr8C}} Chap. IV "Egyptian Mathematics and Astronomy", pp. 7196.</ref>
#'''

# ========== ponemos al fuego la carne =============
sekreta=( ("January", "enero"), ("February", "febrero"), ("March", "marzo"), ("April", "abril"),("May", "mayo"),("June", "junio"),
	("July", "julio"), ("August", "agosto"), ("September", "september"), ("October","octubre"), ("November", "noviembre"), ("December", "diciembre"),
	("Jan.", "ene."), ("Feb.", "feb."), ("Mar.", "mar."), ("Apr.","abr."), ("Jun.", "jun."), 
	("Jul.", "jul."), ("Aug.", "aug."), ("Oct.", "oct."), ("Nov.", "nov."), ("Dec.", "dic."))
idiomas = ( ("italian", "italiano"), ("german", "alemán"), ("french", "francés"), ("russian", "ruso"), ("japanese", "japonés"), ("chinese", "chino"), ("polish", "polaco"))	


def cuece(carnes, condimentos, lang="inglés"):
	cocido=[]
	langset=False
	for k in range(len(carnes)):
		param=carnes[k].split("=")
		if len(param)!=2:
			# Si el pedazo de carne no es de la forma  p = q
			# entonces lo dejamos tal y como está
			cocido.append(carnes[k])
		else:
			# Revisamos si p es uno de los condimentos de la receta	...
			p=param[0].strip()
			q=param[1].strip()
			if p == "language" : 
				langset = True                              # La plantilla indicaba idioma. NO lo añadamos manualmente
				if ("spanish"  in q) or ("Spanish" in q):  # Si en el original decía español
					q = ""                              # entonces nosotros lo descartamos
				else: 
					for x in idiomas:                   # En caso contrario, traducimos el idioma
						if x[0] in q:  q=x[1]			

			if len(q)<1:  # Si el parámetro está vacío.. lo descartamos
				pass				
			elif condimentos.has_key(p):
				r=condimentos[p]  # traducimos el nombre

				###          Receta secreta crunchi          ####
				if r=="isbn":
					q=q.replace("-","")
				if ("fecha" in r) or ("month" in p) or ("día" in r) or ("date" in p):
					for x in sekreta:
						q=q.replace(x[0], x[1])
				###       fin de receta secreta crunchi      ####

				cocido.append( " = ".join([r,q]))  # y lo ponemos en la olla
			else:
				cocido.append(carnes[k])
	if langset==False:       # Si no se detectó parámetro de idioma, asumimos que está en el idioma de la wiki fuente
		cocido.append( "idioma = " + lang )   
	return cocido


# ========== adición de condimentos a la receta =============
def generico(carnes):
	return carnes

def citaweb(carnes):
	# En ocasiones no existe un equivalente directo "coauthor -> coauthors" 
	tr = { 	"title":"título","format":"formato", "url":"url", "archiveurl":"urlarchivo", "archivedate":"fechaarchivo",
		"date":"fecha",	"year":"año","month":"mes","day":"día", "access-date":"fechaacceso","accessdate":"fechaacceso",
		"last":"apellido", "last1":"apellido","first":"nombre", "first1":"nombre",
		"author":"autor","author1":"autor","coauthor":"coautores", "coauthors":"coautores",
		"authorlink":"enlaceautor",
		"work":"obra","quote":"cita",
		"page":"página", "pages":"páginas",
		"publisher":"editorial", "location":"ubicación","language":"idioma",
		"doi":"doi", "DOI":"doi" }

		# Las siguientes opciones tipo "autor3", "last5", etc. no eisten en español, no las traducimos

	cocido=cuece(carnes, tr, lang="inglés")
	return cocido

def citajournal(carnes):

    tr = { "date":"fecha","year":"año","month":"mes","day":"día",
        "title":"título","trans_title":"títulotrad",
        "journal":"publicación","magazine":"publicación",
        "volume":"volumen","issue":"número","number":"número","series":"serie","pages":"páginas","page":"página",
        "location":"ubicación","publisher":"editorial",
        "publication-place":"lugar-publicación","publication-date":"fecha-publicación",
        "language":"idioma",
        "format":"formato",
        "id":"id","isbn":"isbn","issn":"issn","oclc":"oclc","pmid":"pmid","pmc":"pmc","bibcode":"bibcode","doi":"doi",
        "accessdate":"fechaacceso","access-date":"fechaacceso","accessmonth":"mesacceso","accessyear":"añoacceso",
        "url":"url","archiveurl":"urlarchivo","archivedate":"fechaarchivo",
        "separator":"separador","seperator":"separador",
        "last1":"apellido","last":"apellido","surname":"apellido","surname1":"apellido",
        "last2":"apellido2", "surname2":"apellido2","last3":"apellido3", "surname3":"apellido3",
        "last4":"apellido4", "surname4":"apellido4","last5":"apellido5", "surname5":"apellido5",
        "last6":"apellido6", "surname6":"apellido6","last7":"apellido7", "surname7":"apellido7",
        "last8":"apellido8", "surname8":"apellido8","last9":"apellido9", "surname9":"apellido9",
        "first":"nombre", "given":"nombre","first1":"nombre","given1":"nombre",
        "first2":"nombre2","given2":"nombre2","first3":"nombre3","given3":"nombre3",
        "first4":"nombre4","given4":"nombre4","first5":"nombre5","given5":"nombre5",
        "first6":"nombre6","given6":"nombre6","first7":"nombre7","given7":"nombre7",
        "first8":"nombre8","given8":"nombre8",  "first9":"nombre9","given9":"nombre9",
        "author":"autor","author1":"autor",
        "author2":"autor2","author3":"autor3","author4":"autor4","author5":"autor5",
        "author6":"autor6","author7":"autor7","author8":"autor8","author9":"autor9",
        "authorlink":"enlaceautor","authorlink1":"enlaceautor",
        "authorlink2":"enlaceautor2","authorlink3":"enlaceautor3",
        "authorlink4":"enlaceautor4","authorlink5":"enlaceautor5",
        "authorlink6":"enlaceautor6","authorlink7":"enlaceautor7",
        "authorlink8":"enlaceautor8","authorlink9":"enlaceautor9",
        "author-link":"enlaceautor","author1-link":"enlaceautor",
        "author2-link":"enlaceautor2","author3-link":"enlaceautor3",
        "author4-link":"enlaceautor4","author5-link":"enlaceautor5",
        "author6-link":"enlaceautor6","author7-link":"enlaceautor7",
        "author8-link":"enlaceautor8",    "author9-link":"enlaceautor9",
        "author-mask":"máscaraautor","authormask":"máscaraautor",
        "coauthor":"coautor", "coauthors":"coautores",
        "separator":"separador","author-name-separator":"separador-nombres","lastauthoramp":"ampersand",
        "editor":"editor","editor-first":"nombre-editor", "editor-last":"apellidos-editor","editor-link":"enlace-editor",
        "editor1-first":"nombre-editor", "editor1-last":"apellidos-editor", "editor1-link":"enlace-editor",
        "editor2-first":"nombre-editor2", "editor2-last":"apellidos-editor2", "editor2-link":"enlace-editor2",
        "editor3-first":"nombre-editor3", "editor3-last":"apellidos-editor3", "editor3-link":"enlace-editor3",
        "editor4-first":"nombre-editor4", "editor4-last":"apellidos-editor4", "editor4-link":"enlace-editor4",
        "others":"otros", "quote":"cita","ref":"ref",
        "display-authors":"número-autores",
        "laysummary":"resumen","laydate":"fecharesumen", "laysource":"fuenteresumen",
        "postscript":"puntofinal"}

    cocido=cuece(carnes, tr, lang="inglés")
    return cocido

def citalibro(carnes):
	#print "Preparando un libro...\n"
	# De forma intencional se omite trans_title, y similares
	tr = { 	"title":"título","format":"formato", "url":"url",
		"date":"fecha",	"year":"año","month":"mes","day":"día",
		"origyear":"año-original",
		"language":"idioma","in":"idioma",
		"number":"número","issue":"número",
		"accessdate":"fechaacceso","access-date":"fechaacceso",
		"accessmonth":"mesacceso", "accessyear":"añoacceso",
		"publicationdate":"fecha-publicación",
		"series":"serie","serie":"serie",
		"chapter":"capítulo", "chapterurl":"url-capítulo", "chapter-url":"url-capítulo",
		"page":"página", "pages":"páginas","nopp":"sinpp","at":"en",
		"edition":"edición",
		"publisher":"editorial",
		"volume":"volumen",
		"place":"lugar", "location":"lugar",
		"isbn":"isbn","oclc":"oclc","doi":"doi", "DOI":"doi","ID":"id", "ISBN":"isbn", "OCLC":"oclc",
		"last1":"apellido","last":"apellido","surname":"apellido","surname1":"apellido",
		"last2":"apellido2", "surname2":"apellido2",
		"last3":"apellido3", "surname3":"apellido3",
		"last4":"apellido4", "surname4":"apellido4",
		"last5":"apellido5", "surname5":"apellido5",
		"first":"nombre", "given":"nombre",
		"first1":"nombre","given1":"nombre",
		"first2":"nombre2","given2":"nombre2",
		"first3":"nombre3","given3":"nombre3",
		"first4":"nombre4", "given4":"nombre4",
		"first5":"nombre5","given5":"nombre5",
		"author":"autor","author1":"autor1","author2":"autor2","author3":"autor3","author4":"autor4","author5":"autor5",
		"authorlink":"enlaceautor","authorlink1":"enlaceautor1","authorlink2":"enlaceautor2",
		"authorlink3":"enlaceautor3","authorlink4":"enlaceautor4","authorlink5":"enlaceautor5",
		"author-link":"enlaceautor","author1-link":"enlaceautor1","author2-link":"enlaceautor2",
		"author3-link":"enlaceautor3","author4-link":"enlaceautor4","author5-link":"enlaceautor5",
		"author-mask":"máscaraautor","authormask":"máscaraautor",
		"coauthor":"coautor", "coauthors":"coautores",
		"separator":"separador","author-name-separator":"separador-nombres","lastauthoramp":"ampersand",
		"editor":"editor", "editor-first":"nombre-editor", "editor-last":"apellido-editor","editor-link":"enlace-editor",
		"editor1-first":"nombre-editor", "editor1-last":"apellido-editor", "editor1-link":"enlace-editor",
		"editor2-first":"nombre-editor2", "editor2-last":"apellido-editor2", "editor2-link":"enlace-editor2",
		"editor3-first":"nombre-editor3", "editor3-last":"apellido-editor3", "editor3-link":"enlace-editor3",
		"others":"otros", "quote":"cita","laysummary":"resumen","laydate":"fecha-resumen", "postscript":"puntofinal",
		"contribution":"capítulo", "editors":"editor"}
		
	cocido=cuece(carnes, tr, lang="inglés")
	return cocido



def TRADUCE(fuente,compacto=True):
	source=fuente
	source=re.sub("\n","",source)   #Quitamos saltos de línea para que las regex y los splits funcionen bonito
	u=re.search("(.*){{(.*)}}(.*)",source)   # Separamos el contenido externo de la plantilla del interno
	if not  u :
		return "No puedo detectar una plantilla"

	pan=u.group(1)   # Antes de la plantilla
	relleno= u.group(2)  # Interior de la plantilla
	tapa=u.group(3)     # Posterior a la plantilla

	relleno=re.sub("\s*\|\s*", "|", relleno)  # Quitamos espacios antes y después de las barras

	carnes = relleno.split("|")     # Creamos una lista de pares de parámetro=valor

	p = carnes[0].strip().lower()  # El primer campo es en realidad el nombre de la plantilla

	#print p
	#print fuente
	# A pesar de la redundancia, vamos a hacer las cosas de forma
	# ordenada, permitiendo que cada plantilla tenga su propia función
	# y así poder ajustes personalizados para cada plantilla.
	if compacto:
		sep = " | "
	else:
		sep = "\n|"
	if p == "cite book":
		p = "{{cita libro"+sep
		parrilla=citalibro(carnes[1:])
	elif p=="cite web":
		p = "{{cita web"+sep
		parrilla=citaweb(carnes[1:])
	elif p=="cite journal":
		p = "{{cita publicación"+sep
		parrilla=citajournal(carnes[1:])
	else:
		p="{{"+p+sep
		parrilla=generico(carnes[1:])
	
	burguer = sep.join(parrilla)
	hamburguesa = "".join([pan, p,burguer, "}}", tapa]) 
	return hamburguesa