Segunda iteración
Como bien dijimos al inicio, necesitamos hacer el programa más modular y para conseguir esto debemos realizar nuestro código orientado a objetos.
Para ello debemos hacer las abstracciones necesarias de forma que podamos construir clases que contengan los métodos que logren nuestros objetivos.
Requisitos
Hagamos una lista de los componentes que necesitamos construir, con ello sabremos que debemos tener para que nuestro programa sea más completo:
- Un parser, este objeto nos permitirá leer el texto y manejar las otras clases.
- Reglas, haremos una regla por cada tipo de bloque, esto nos hará capaces de detectar que tipo de bloque tenemos y que formato debemos aplicarle.
- Filtros, con ellos incorporaremos expresiones regulares para poder manejar algunos elementos internos.
- Handlers, estos manejadores serán utilizados por el parser para generar la salida procesada. Cada handler podrá manejar un tipo diferente de etiquetas.
Esta clase nos permitirá manejar ciertos tipos de etiquetas para las sálidas, veamos el código que puede contener:
Luego debemos construir una súper clase Handlers, que nos permitirá administrar los diferentes handlers que necesitemos. Para ello veremos el siguiente código:
class Handler: def callback(self, prefix, name, *args): method = getattr(self, prefix+name, None) if callable(method): return method(*args) def start(self, name): self.callback('start_', name) def end(self, name): self.callback('end_', name) def sub(self, name): def substitution(match): result = self.callback('sub_', name, match) default = match.group(0) return result or default return substitution
Si ahora hacemos un pequeño ejercicio podremos ver nuestro avance hasta ahora:
>>> from handlers import HTMLRenderer >>> handler = HTMLRenderer() >>> import re >>> re.sub(r'\*(.+?)\*', handler.sub('emphasis'), 'Esto*es una* prueba') 'Esto <em>es una</em> prueba'
Como vemos en el llamado anterior, primero importamos nuestra clase HTMLRenderer que es nuestro handler, luego importamos re con el cual manejaremos las expresiones regulares, entonces pasamos a re.sub la expresión y el método con el cual debe aplicarla, luego el texto y por último vemos que la salida ha generado el código HTML necesario.
Reglas
Una vez que tenemos los handlers, es hora de hacer las reglas estas nos ayudaran a darle un destino a los diferentes bloques, sin embargo, debe ser orientado a objetos de forma que no terminemos con una gran cantidad de bloques if anidados para validar todos los casos.
También debemos tener una súper clase que administre nuestras reglas, veamos el siguiente código que contiene a la súper clase.
class Rule: def action(self, block, handler): handler.start(self.type) handler.feed(block) handler.end(self.type) return True
Como vemos el método action() recibe el bloque y el tipo de handler que debe utilizar, con ello podrá distinguir que bloque debe aplicar a lo que está recibiendo por parámetros y así finalizar el código que debe imprimir.
Con esto finalizamos el tutorial y dejamos en manos de cada quien continuar hasta tener el proyecto listo bajos las directrices dadas en el inicio en la primera parte de este tutorial.