""" /* * gentabtex.py 1.2 * gentabtex.py: high layer interface for rendering LaTeX tables. * * Copyright (C) Manuel Gutierrez Algaba, 2004, algaba@seul.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ carmonense@andaluciajunta.es changes version : date: 0.1 : March 2004: added automatical balancing of columns. 1.2 : January 2006: added operators todas todasmenos en desdehasta """ separador = " }& " terminador = r"\\" + "\n" class distribuidor: class pesocolumna: def __init__(self): self.filas = [] def anyadefila(self, fila): self.filas.append(fila) def dapeso(self): s= 0 for i in self.filas: s += len(i) return s def dapesonor(self): return self. pesonormalizado def hazpesonor(self, p): self. pesonormalizado = p def normalizapeso(self, total, factor): self.pesonormalizado = factor * ( self.dapeso() * 1.0 / total) #print "Peso normalizado", self.pesonormalizado, "total ", total, "factor", factor, "peso", self.dapeso(), "relativo", ( self.dapeso() * 1.0 / total) def __cmp__(self, o): p= self.dapeso() po = o.dapeso() if p x ! ! ! ! V y """ def calculapesos(self): self.dist = distribuidor() for j in xrange(0, self.dimx()): self.dist.anyadecolumna() for i in xrange(0, self.dimy()): if self.mmatriz. has_key((i,j)): self.dist.anyadeencolumna(self.mmatriz[(i,j)]) def imprimepesos(self): self.dist.imprimepesos() def __init__(self): self.mmatriz = {} def anyade(self, posx, posy, el): self.mmatriz[(posy, posx) ] = el def __getitem__(self, dupla): return self.mmatriz[dupla] def dimx(self): return max(map( lambda(x):x.__getitem__(1), (self.mmatriz.keys()))) + 1 def dimy(self): return max(map( lambda(x):x.__getitem__(0), (self.mmatriz.keys()))) + 1 def __str__(self): #print "Dimensiones", self.dimy(), self.dimx() a= "" for i in xrange(0, self.dimy()): for j in xrange(0, self.dimx()): if self.mmatriz. has_key((i,j)): if type(self.mmatriz[(i,j)]) != type(""): a += str(self.mmatriz[(i,j)]) else: a += self.mmatriz[(i,j)] a += separador a = a[:-(len(separador))] a += terminador return a def imprime(self): print self.mmatriz def repartepesos(self, tamanayototal, tamanyominimo): return self.dist. repartepesos( tamanayototal, tamanyominimo) def dapesosformatostex(self): return self. dist. dapesosformatostex() class filasenorden: def __init__(self, columna=0): self.filaorden=1 self.listafilas=[] self.columna= columna def anyade(self, t): self.filaorden += 1 self.listafilas.append(t) def devnumerofilas(self): return len(self.listafilas) def devfila(self, nfila, col): if col==self.columna: return self.listafilas[nfila] def escribeenmatriz(self, matriz): j = 1 for i in self.listafilas: matriz. anyade( self.columna, j, i ) j += 1 class columnasenorden: def __init__(self, fila=0): self.columnaorden=1 self.listacolumnas=[] self.fila= fila def anyade(self, t): self.columnaorden += 1 self.listacolumnas.append(t) def devnumerocolumnas(self): return len(self.listacolumnas) def devcolumna(self, nfila, col): if nfila==self.fila: return self.listacolumnas[col] def escribeenmatriz(self, matriz): j = 0 for i in self.listacolumnas: matriz. anyade( j, self.fila, i ) j += 1 class cequis: def __init__(self, columna, filas, columnanum=None, extendido= None): self.columna = columna self.filas = filas self. columnanum = columnanum self. extendido = extendido def escribeenmatriz(self, matriz): if self.columna=="ultimacolumna": self.escribe1(matriz) else: if not self. columnanum is None: self. escribe2(matriz) elif self.columna == "todafila": #return for i in xrange(0,matriz.dimy()): puedeescribir = 0 #print self.extendido, self.filas for j in self.filas: if self.esvalido(j, (i,0), matriz): puedeescribir = 1 break if puedeescribir: for c in xrange(1, matriz.dimx()): matriz.anyade( c, i, 'x') #print "trastodafila" , matriz def escribe2(self, matriz): def esextendidovalido(matriz, i): for j in self. extendido: if self.esvalido( j, (i, 0), matriz ): return 1 c= self. columnanum - 1 if self.filas == "todas" or self.filas=="toda": for i in xrange(1,matriz.dimy()): matriz.anyade( c + 1, i , 'x') if self.filas == "todamenos" or self.filas=="todasmenos": for i in xrange(1,matriz.dimy()): puedeescribir = 1 #print self.extendido for j in self. extendido: if self.esvalido( j, (i, 0), matriz ): puedeescribir = 0 if puedeescribir: matriz.anyade( c+1, i, 'x') elif self.filas=="desdehasta": #print "desdehasta" def escribetramovalido(matriz, j,c): for k in xrange(j, matriz.dimy()): matriz.anyade( c+1, k, 'x') if esextendidovalido(matriz, k): break for i in xrange(0,matriz.dimy()): #print self.extendido if esextendidovalido( matriz, i): matriz.anyade( c+1, i, 'x') escribetramovalido(matriz, i+1, c) break elif self.filas=="en": for i in xrange(0,matriz.dimy()): puedeescribir = 0 for j in self. extendido: if self.esvalido( j, (i, 0), matriz ): puedeescribir = 1 if puedeescribir: matriz.anyade( c+1, i, 'x') def esvalido(self, duplacond, duplacoor, matriz): """ duplacond es de la forma: ('c', 'subcarpeta') duplacoor: (0, 1) (y, x) matriz:{(9, 0): 'Eliminar subcarpetas y archivos', (8, 0): 'Atributos extendidos de escritorio', (3, 0): 'Atributos de lectura' ... } Se trata de decidir si en matriz, en la posicion (0,1) hay un texto que contenga la cadena 'subcarpeta' """ try: s = matriz[duplacoor] except KeyError: return 0 #matriz.imprime() #print "duplacond", str(s), duplacond, duplacoor if duplacond[0]=='c' and type(s)==type(""): return s.find(duplacond[1] )!=-1 def escribe1(self, matriz): c = matriz.dimx() - 1 j = 1 for i in self.filas: matriz.anyade(c, j, i) j +=1 class ccabecera: def __init__(self, lista ): self.lista= lista def escribeenmatriz(self, matriz): j = 0 #print len(self.lista) for i in self.lista : matriz. anyade( j, 0, i ) j +=1 def ncolumnas(self): return len(self.lista) def __init__(self): self.lamatrizdispersa= gentabtex.matrizdispersa() self. ofilasenorden = gentabtex.filasenorden() self. todasfilasenorden = [ self. ofilasenorden ] self. todosequis = [] self. ocolumnasenorden = gentabtex.columnasenorden() self. todascolumnasenorden = [ self. ocolumnasenorden ] self. aspcab ="" self. acoletilla="" def coletilla(self, colt): self. acoletilla = colt return self def sync(self): for i in self. todasfilasenorden: i. escribeenmatriz(self. lamatrizdispersa) for i in self. todascolumnasenorden: i. escribeenmatriz(self. lamatrizdispersa) self.ocabecera. escribeenmatriz(self. lamatrizdispersa) for i in self. todosequis: i. escribeenmatriz(self. lamatrizdispersa ) return self def __str__(self): if self.aspcab=="": self.aspcab="{" + "l" * self. lamatrizdispersa.dimx() +"}" a=r"""\begin{tabular}""" + self.aspcab + "\n" a += str(self. lamatrizdispersa) a+= r"""\end{tabular}""" a+=self. acoletilla return a def imprimepesos(self): self. lamatrizdispersa. imprimepesos() def otrafilaenorden(self,col): self. ofilasenorden = gentabtex.filasenorden(col) self. todasfilasenorden. append(self. ofilasenorden) return self def otracolumnaenorden(self,col): self. ocolumnasenorden = gentabtex.columnasenorden(col) self. todascolumnasenorden. append(self. ocolumnasenorden) return self def otraen(self, columna): return self. otrafilaenorden(columna) def columnas(self, acolumna ): self. ofilasenorden. columna= acolumnas return self def co(self, acolumna): return self. columnas(acolumna) def anchuras(self, nanchuras ): self.nanchuras = anchuras return self def enfilaorden(self, dato): self. ofilasenorden.anyade(dato) return self def encolumnaorden(self,dato): self. ocolumnasenorden.anyade(dato) return self def en(self, dato): if type(dato) == type([]): for i in dato: self.enfilaorden(i) return self else: return self. enfilaorden(dato) def fil(self, dato): if type(dato) == type([]): for i in dato: self.encolumnaorden(i) self. otracolumnaenorden(self. ocolumnasenorden.fila + 1) return self else: return self. encolumnaorden(dato) def cabecera(self, listacab): self.ocabecera= gentabtex.ccabecera(listacab) return self def cab(self,listacab): return self.cabecera(listacab) def equis(self, columna, filas, extendido=None): if type(columna)==type(1): self.todosequis.append(gentabtex.cequis(None, filas, columnanum=columna, extendido=extendido)) else: self.todosequis.append(gentabtex.cequis(columna, filas)) return self def defaspectocolumna(self, asp): """ {p{2cm}p{2cm}p{0.5cm}p{0.5cm}p{0.5cm}p{0.5cm}} """ self. aspcab = asp return self def daaspectautoma(self): self. aspcab = self. lamatrizdispersa. dapesosformatostex() return self def repartepesos(self, tamanyototal, tamanyominimo): self. lamatrizdispersa. repartepesos(tamanyototal, tamanyominimo) return self def calculapesos(self): self. lamatrizdispersa. calculapesos() return self if __name__=='__main__': import sys f=open("tablasejemplo.tex", "w") #sys.stdout=f separador = " & " g = gentabtex().en("rojo").en("azul").en("verde").en("amarillo"). \ cab(["colores", "buen gusto", "coche", "gallumbos", "fruta"]).otraen(1). \ en(["es dificil conseguir algo que no sobresalte y quede bien", "los pantalones, camisas, color discreto donde los haya", "si no es fuerte o amerillento", "hortero en la mayoria de las ocasiones"]).otraen(2).\ en(["implica conduccion agresiva", "es un color que como tal rara vez se da, es mas corriente en los nortes", "no esta de moda", "es el color que mejor se ve"]).\ equis("ultimacolumna", ["tomate", "alga", "melon", "melon"]).\ defaspectocolumna("") g.sync() print g print r"\\" g. lamatrizdispersa. calculapesos() #g.imprimepesos() g.repartepesos(8, 0.3) g. daaspectautoma() print g print r"\\" g2 = gentabtex().en(["Recorrer carpetas/Ejecutar archivo", "Listar carpeta/Leer datos", "Atributos de lectura", "Atributos extendidos de lectura", "Crear archivos/Escribir datos", "Crear carpetas/Anexar datos", "Atributos de escritura", "Atributos extendidos de escritura", "Eliminar subcarpetas y archivos", "Eliminar", "Permisos de lectura", "Cambiar permisos", "Tomar posesión", "Sincronizar"]).\ cab([0,1,2,3,4,5,6]). \ equis(1, "toda").equis(2, "todamenos", [('c', 'subcarpeta'), ('c', 'Cambiar permisos')]).\ equis("todafila", [('c', 'Permisos de lectura'), ('c', 'Sincronizar')]).\ equis(3, "desdehasta", (('c',"Recorrer"),('c', "extendidos"))).\ equis(4, "desdehasta", (('c',"Recorrer"),('c', "extendidos"))).\ equis(5, "desdehasta", (('c',"Listar"),('c', "extendidos"))).\ equis(5, "en", [('c',"extendidos de escritura")]).\ equis(6, "desdehasta", (('c',"Crear archivos"),('c', "Atributos de escritura"))).\ coletilla("""\\\\ 1 control total 2 modificar 3 leer y ejecutar 4 listar el contenido de la carpeta 5 lectura 6 escribir """).\ sync() # daaspectautoma() #calculapesos(). repartepesos(6, 0.5). print g2 #print r"\\" tabcabtec = gentabtex().cab(["Protocolo", "Velocidad nominal", "Frecuencia base", "Capacidad exigible al cable", "Categoría de cable requerida"]).\ fil([ "10Base-T", "10 Mbps", "10 MHz", "10 MHz", "Cat-3"]).\ fil(["100Base-T4", "100 Mbps", "12.5 MHz", "12.5 MHz", "Cat-3"]).\ fil(["802.12 (VG)", "100 Mbps", "15 MHz", "15 MHz", "Cat-3"]).\ fil(["100Base-TX", "100 Mbps", "31.25 MHz", "80 MHz", "Cat-5"]).\ fil(["FDDI (*)", "100 Mbps", "31.25 MHz", "80 MHz", "Cat-5"]).\ fil(["ATM (**)", "155 Mbps", "77.5 MHz", "100 MHz", "Cat-5"]).\ sync().calculapesos().repartepesos(6, 0.5). daaspectautoma() print tabcabtec f.close()