diff --git a/textlistrenderer.py b/textlistrenderer.py
index d9e9531..09e2fb4 100644
--- a/textlistrenderer.py
+++ b/textlistrenderer.py
@@ -12,10 +12,101 @@ import dateutils
 from db import Config
 
 
+class Column(object):
+    __slots__ = ["title", "width", "formater", "colorizer"]
+
+    def __init__(self, title, width, formater, colorizer = None):
+        """
+        formater is a callable which accepts a task and returns a string
+        colorizer is another callable which takes accepts a task and returns a
+        color or None
+        """
+        self.title = title
+        self.width = width
+        self.formater = formater
+        self.colorizer = colorizer
+
+
+    def createHeader(self):
+        return self.title.ljust(self.width)
+
+
+    def createCell(self, task):
+        value = self.formater(task)
+
+        if self.colorizer:
+            color = self.colorizer(task)
+        else:
+            color = None
+
+        if color:
+            cell = color
+        else:
+            cell = ""
+        cell = cell + value.ljust(self.width)
+        if color:
+            cell = cell + C.RESET
+        return cell
+
+
+class TitleFormater(object):
+    def __init__(self, width):
+        self.width = width
+
+    def __call__(self, task):
+        title = task.title
+        hasDescription = task.description != ""
+        maxLength = self.width
+        if hasDescription:
+            maxLength -= 1
+        if len(title) > maxLength:
+            title = title[:maxLength - 1] + ">"
+        else:
+            title = title.ljust(maxLength)
+        if hasDescription:
+            title = title + "*"
+
+        return title
+
+
+def urgencyColorizer(task):
+    if task.urgency > 75:
+        return C.RED
+    elif task.urgency > 50:
+        return C.PURPLE
+    else:
+        return None
+
+
+def statusColorizer(task):
+    if task.status == "started":
+        return C.BOLD
+    else:
+        return None
+
+
+def timeLeftFormater(task):
+    dueDate = task.dueDate
+    if dueDate:
+        return dateutils.formatTimeDelta(dueDate - datetime.today().replace(microsecond=0))
+    else:
+        return ""
+
+
 class TextListRenderer(object):
     def __init__(self, out):
         self.out = out
 
+        titleWidth = int(Config.byName("TEXT_WIDTH").value)
+        self.columns = [
+            Column("ID"            , 3          , lambda x: str(x.id))           ,
+            Column("Title"         , titleWidth , TitleFormater(titleWidth))     ,
+            Column("U"             , 3          , lambda x: str(x.urgency)       , colorizer=urgencyColorizer) ,
+            Column("S"             , 1          , lambda x: x.status[0].upper()  , colorizer=statusColorizer)  ,
+            Column("Creation date" , 16         , lambda x: str(x.creationDate)) ,
+            Column("Time left"     , 10         , timeLeftFormater)
+            ]
+
 
     def addTaskList(self, project, taskList):
         self._renderTaskListHeader(project.name)
@@ -27,16 +118,11 @@ class TextListRenderer(object):
         pass
 
 
-    def _getTaskFormat(self):
-        """@return: task format as a string with placeholder"""
-        width=Config.byName("TEXT_WIDTH").value
-        return "%(id)-3s|%(title)-"+width+"s|%(urgency)-3s|%(status)-1s|%(creationDate)-16s|%(timeLeft)-10s"
-
-
     def _renderTaskListHeader(self, projectName):
         width=int(Config.byName("TEXT_WIDTH").value)
-        line = self._getTaskFormat() % dict(id="ID", title="Title", urgency="U",
-                                       status="S", creationDate="Creation date", timeLeft="Time left")
+
+        cells = [x.createHeader() for x in self.columns]
+        line = "|".join(cells)
         print >>self.out
         print >>self.out, C.CYAN+projectName.center(30+width)+C.RESET
         print >>self.out, C.BOLD+line+C.RESET
@@ -44,31 +130,6 @@ class TextListRenderer(object):
 
 
     def _renderTaskListRow(self, task):
-        title = task.title
-        hasDescription = task.description != ""
-        maxLength = int(Config.byName("TEXT_WIDTH").value)
-        if hasDescription:
-            maxLength -=1
-        if len(title) > maxLength:
-            title = title[:maxLength - 1] + ">"
-        if hasDescription:
-            title = title.ljust(maxLength) + "*"
-
-        status = task.status[0].upper()
-        if status=="S":
-            status=C.BOLD+status+C.RESET
-        creationDate = str(task.creationDate)[:-3]
-        if task.dueDate:
-            timeLeft=dateutils.formatTimeDelta(task.dueDate - datetime.today().replace(microsecond=0))
-        else:
-            timeLeft=""
-        if int(task.urgency)>75:
-            urgency=C.RED+str(task.urgency)+" "+C.RESET
-        elif int(task.urgency)>50:
-            urgency=C.PURPLE+str(task.urgency)+" "+C.RESET
-        else:
-            urgency=task.urgency
-
-        print >>self.out, self._getTaskFormat() % dict(id=str(task.id), title=title, urgency=urgency, status=status,
-                                       creationDate=creationDate, timeLeft=timeLeft)
+        cells = [column.createCell(task) for column in self.columns]
+        print >>self.out, "|".join(cells)
 # vi: ts=4 sw=4 et

