<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>run_tests</filename>
    </added>
    <added>
      <filename>templatetags/__init__.py</filename>
    </added>
    <added>
      <filename>tests/__init__.py</filename>
    </added>
    <added>
      <filename>tests/django-headline.py</filename>
    </added>
    <added>
      <filename>tests/font.ttf</filename>
    </added>
    <added>
      <filename>tests/settings.py</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,294 +1,406 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2009 Igor &quot;SkAZi&quot; Potapov &lt;igor@poatpoff.org&gt;
-# GNU General Public License
-#
-# http://github.com/SkAZi/django-headline/
-
-from django import template
-from django.conf import settings
-from django.utils.encoding import smart_str
-from django.utils.safestring import mark_safe
-from django.template import TemplateSyntaxError
-
-import Image, ImageFont, ImageDraw, ImageChops
-from os import path
-try:
-    from hashlib import md5
-except:
-    from md5  import new as md5
-import re
-
-HEADLINE_CACHE_DIR = getattr(settings, 'HEADLINE_CACHE_DIR', 'upload')
-HEADLINE_NO_CACHE = getattr(settings, 'HEADLINE_NO_CACHE', False)
-HEADLINE_FONTS_DIR = getattr(settings, 'HEADLINE_FONTS_DIR', 'fonts')
-HEADLINE_CLASSES = getattr(settings, 'HEADLINE_CLASSES', {})
-HEADLINE_TEMPLATE = getattr(settings, 'HEADLINE_TEMPLATE',
-        u&quot;&quot;&quot;&lt;img alt=&quot;%(text)s&quot; src=&quot;%(url)s&quot; class=&quot;png&quot; width=&quot;%(width)s&quot; height=&quot;%(height)s&quot; /&gt;&quot;&quot;&quot;)
-HEADLINE_PNG_OPTIMIZER = getattr(settings, 'HEADLINE_PNG_OPTIMIZER', False)
-
-AVIABLE_DECORATIONS = ('underline', 'strikeout')
-AVIABLE_SPLITTERS = ('br', 'all', 'none')
-
-ENTITIES = (
-    (u'&amp;laquo;', u'&#171;'), (u'&amp;raquo;', u'&#187;'),
-    (u'&amp;bdquo;', u'&#8222;'), (u'&amp;ldquo;', u'&#8220;'),
-    (u'&amp;lquo;', u'&#8221;'),  (u'&amp;ndash', u'&#8211;'),
-    (u'&amp;mdash;', u'&#8212;'), (u'&amp;amp;', u'&amp;'),
-    (u'&amp;quot;', u&quot;\&quot;&quot;), (u'&amp;apos;', u&quot;'&quot;),
-    (u'&amp;reg;', u'&#174;'),   (u'&amp;copy;', u'&#169;'),
-    (u'&amp;trade;', u'&#8482;'), (u'&amp;sect;', u'&#167;'),
-    (u'&amp;euro;', u'&#8364;'),  (u'&amp;nbsp;', u' '),
-    (u'&amp;rsquo;', u'&#8217;'), (u'&amp;Prime;', u'&#8243;'),
-    (u'&amp;le;', u'&#8804;'),    (u'&amp;ge;', u'&#8805;'),
-    (u'&amp;lt;', u'&lt;'),    (u'&amp;gt;', u'&gt;'),
-    (u'\n', u''),       (u'\t', u'    '),
-)
-
-
-def _clean_text(text):
-    &quot;&quot;&quot;
-        Clean text from extra spaces and replaces
-        html-entities by unicode symbols
-    &quot;&quot;&quot;
-    text = text.strip()
-    for (s, r) in ENTITIES:
-        text = re.sub(s, r, text)
-    return text
-
-
-
-def _img_from_text(text, font, size=12, color='#000', decoration=[]):
-    &quot;&quot;&quot;
-        Draws text with font, size, color and decoration parameters.
-        Caches images and returns (html or object, width, size) of
-        new or exists image
-    &quot;&quot;&quot;
-    image_path = path.join(settings.MEDIA_ROOT, HEADLINE_CACHE_DIR)
-    font_path = path.join(settings.MEDIA_ROOT, HEADLINE_FONTS_DIR)
-
-    id = &quot;headline-%s&quot; % md5(smart_str(''.join((text, font, size, color, ''.join(decoration))))).hexdigest()
-    image_file = path.join(image_path, &quot;%s.png&quot; % id)
-    
-    size = int(size)
-
-    if not path.isfile(image_file) or HEADLINE_NO_CACHE:
-        
-        font = ImageFont.truetype(path.join(font_path, font), size)
-        width, height = font.getsize(text)
-        
-        ### Init surfaces
-        image = Image.new(&quot;RGB&quot;, (width, height), (0,0,0))
-        alpha = Image.new(&quot;L&quot;, image.size, &quot;black&quot;)
-        imtext = Image.new(&quot;L&quot;, image.size, 0)
-        draw = ImageDraw.Draw(imtext)
-        
-        ### Real Drawings on alpha with white color
-        draw.text((0, 0), text, font=font, fill=&quot;white&quot;)
-        if 'underline' in decoration:
-            draw.line((0 + size/20, height*3/4, width - size/20, height*3/4),
-                      fill=&quot;white&quot;, width=size/20)
-        if 'strikeout' in decoration:
-            draw.line((0 + size/20, height/2, width - size/20, height/2),
-                      fill=&quot;white&quot;, width=size/20)
-            
-        ### Alpha color black-magic
-        alpha = ImageChops.lighter(alpha, imtext)
-        solidcolor = Image.new(&quot;RGBA&quot;, image.size, color)
-        immask = Image.eval(imtext, lambda p: 255 * (int(p != 0)))
-        image = Image.composite(solidcolor, image, immask)
-        image.putalpha(alpha)
-        image.save(image_file, &quot;PNG&quot;)
-        
-        if HEADLINE_PNG_OPTIMIZER:
-            from os import system
-            system(HEADLINE_PNG_OPTIMIZER % {&quot;file&quot;: image_file})
-    
-    else:
-        width, height = Image.open(image_file).size
-        
-    return &quot;%s%s/%s.png&quot; % \
-           (settings.MEDIA_URL, HEADLINE_CACHE_DIR, id), width, height
-
-
-
-def _image_list(output, klass, splitter, object=False):
-    &quot;&quot;&quot;
-        Pictures and html or objects generator by split options
-    &quot;&quot;&quot;
-    if splitter:
-        chunks = splitter.split(output)
-    else:
-        chunks = (output, )
-        
-    for text in chunks:
-        text = _clean_text(text)
-        if not text: continue
-
-        url, width, height = _img_from_text(text, **klass)
-        obj = { 'text': text,
-                'url': url,
-                'width': width,
-                'height': height }
-
-        if object:
-            yield obj
-        else:
-            yield HEADLINE_TEMPLATE % obj
-    
-    
-def _create_splitter(splitting):
-    &quot;&quot;&quot;
-        Creates regular expression text splitter
-    &quot;&quot;&quot;
-    if splitting == 'br':
-        return re.compile(r&quot;&lt;br */?&gt;&quot;), &quot;&lt;br /&gt;&quot;
-    elif splitting == 'all':
-        return re.compile(r&quot;&lt;br */?&gt;| *&quot;), &quot; &quot;
-    else:
-        return False, &quot;&quot;
-
-
-
-def _get_class( klass ):
-    &quot;&quot;&quot;
-        Get or create real class parameters by options string
-    &quot;&quot;&quot;
-    params = re.split(r&quot;, *&quot;, klass.strip('&quot;'))
-    typ = False
-
-    if len(params) &gt; 2:
-        decoration = []
-        for i in AVIABLE_DECORATIONS:
-            if i in params:
-                decoration.append(i)
-                params.remove(i)
-        
-        klass = {
-            'font': params[0],
-            'size': params[1],
-            'color': params[2],
-            'decoration': decoration
-        }
-        
-        if len(params) &gt; 3:
-            typ = params[3]
-            
-        return klass, typ
-        
-    elif params &gt; 0:
-        klass = params[0]
-        if len(params) &gt; 1:
-            typ = params[1]
-
-        try:
-            return HEADLINE_CLASSES[klass], typ
-        except:
-            raise TemplateSyntaxError('There is no class: %s' % klass)
-        
-    return False, False
-
-    
-    
-register = template.Library()
-
-
-@register.filter(name=&quot;headline&quot;)
-def do_text_image_filter(value, klass):
-    klass, typ = _get_class(klass)
-    if not klass:
-        raise TemplateSyntaxError('Headline filter needs in parameter' )
-        
-    return mark_safe(TextImageNode(value, klass, typ).show())
-
-do_text_image_filter.is_safe = True
-
-
-@register.tag(name=&quot;headline&quot;)
-def do_text_image_tag(parser, token):
-    
-    params = token.split_contents()
-    
-    klass, typ = _get_class(params[1])
-        
-    if not klass:
-        raise TemplateSyntaxError('Headline tag needs in parameter' )
-        
-    if not typ:
-        typ = &quot;br&quot;
-    
-    nodelist = parser.parse(('endheadline',))
-    parser.delete_first_token()
-        
-    return TextImageNode(nodelist, klass, typ)
-
-
-class TextImageNode(template.Node):
-    
-    def __init__(self, nodelist, klass, splitting=&quot;br&quot;):
-        self.klass = klass
-        self.splitter, self.joiner = _create_splitter(splitting)
-        self.nodelist = nodelist
-        
-    def show(self):
-        &quot;&quot;&quot; If filter &quot;&quot;&quot;
-        output = self.nodelist
-        return self.joiner.join(
-            _image_list( output, self.klass, self.splitter )
-        )
-        
-    def render(self, context):
-        &quot;&quot;&quot; If tag &quot;&quot;&quot;
-        output = self.nodelist.render(context)
-        return self.joiner.join(
-            _image_list( output, self.klass, self.splitter )
-        )
-
-
-
-@register.tag(name=&quot;headlines&quot;)
-def do_text_images_tag(parser, token):
-    params = token.split_contents()
-        
-    if len(params) &gt; 4 and params[-3] == 'as':
-        klass, typ = _get_class(params[-1])
-        
-        output = []
-        for st in params[1:-3]:
-            if st.startswith('&quot;') and st.endswith('&quot;'):
-                output.append(st.strip('&quot;'))
-            else:
-                output.append(parser.compile_filter(st))
-                
-        return TextImagesNode(output, params[-2], klass, typ)
-           
-    else:
-        raise TemplateSyntaxError('Hedlines tag must be like {% headlines &lt;list of vars&gt; as &lt;context_var&gt; &lt;class_or_params&gt; %}' )
-
-
-class TextImagesNode(template.Node):
-    def __init__(self, output, to, klass, splitting):
-        self.klass = klass
-        self.output = output
-        self.to = to
-        self.splitter, self.joiner = _create_splitter(splitting)
-        
-    def _flatten_data(self, output, context):
-        &quot;&quot;&quot;
-            Generator of images from all-typed parameters
-        &quot;&quot;&quot;
-        for token in output:
-            if isinstance(token, (unicode, str)):
-                token = (token, )
-            else:
-                token = token.resolve(context)
-                if not isinstance(token, (list, tuple, dict)):
-                    token = (token, )
-                
-            for tk in token:
-                for obj in _image_list( tk, self.klass, self.splitter, True):
-                    yield obj
-    
-    def render(self, context):
-        context[self.to] = [item for item in self._flatten_data(self.output, context)]
-        return ''
\ No newline at end of file
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2009 Igor &quot;SkAZi&quot; Potapov &lt;igor@poatpoff.org&gt;
+# GNU General Public License
+#
+# http://github.com/SkAZi/django-headline/
+
+from django import template
+from django.conf import settings
+from django.utils.encoding import smart_str
+from django.utils.safestring import mark_safe
+from django.template import TemplateSyntaxError
+
+from htmlentitydefs import name2codepoint
+import Image, ImageFont, ImageDraw, ImageChops
+from os import path
+try:
+    from hashlib import md5
+except:
+    from md5 import new as md5
+import re
+
+HEADLINE_CACHE_DIR = getattr(settings, 'HEADLINE_CACHE_DIR', 'upload')
+HEADLINE_NO_CACHE = getattr(settings, 'HEADLINE_NO_CACHE', False)
+HEADLINE_FONTS_DIR = getattr(settings, 'HEADLINE_FONTS_DIR', 'fonts')
+HEADLINE_CLASSES = getattr(settings, 'HEADLINE_CLASSES', {})
+HEADLINE_TEMPLATE = getattr(settings, 'HEADLINE_TEMPLATE',
+        u&quot;&quot;&quot;&lt;img alt=&quot;%(text)s&quot; src=&quot;%(url)s&quot; class=&quot;png&quot; width=&quot;%(width)s&quot; height=&quot;%(height)s&quot; /&gt;&quot;&quot;&quot;)
+HEADLINE_PNG_OPTIMIZER = getattr(settings, 'HEADLINE_PNG_OPTIMIZER', False)
+
+AVIABLE_SPLITTERS = ('br', 'all', 'none')
+AVIABLE_DECORATIONS = {
+    'underline': 0,
+    'strikeout': 0,
+    'opacity': 1,
+    'rotate': 0,
+}
+
+ENTITY_CONVERTER = re.compile(r'(?:&amp;#x([a-fA-F\d]{1,4});)|(?:&amp;#(\d{1,5});)|(?:&amp;([a-zA-Z\d]+);)')
+
+
+
+def _convertentity(m):
+    &quot;&quot;&quot;
+        Convert single entity into unicode character
+    &quot;&quot;&quot;
+    ### If it is hex entity like &amp;#xFF;
+    if m.group(1):
+        return unichr(int(m.group(1), 16))
+    ### If it is dec entity like &amp;#255;
+    elif m.group(2):
+        return unichr(int(m.group(2)))
+    ### If it is named entity like &amp;laquo;
+    elif m.group(3) and m.group(3) in name2codepoint:
+        return unichr(name2codepoint[m.group(3)])
+    ### Dont touch all other 
+    else:
+        return m.group(0)
+
+
+
+def _clean_text(text):
+    &quot;&quot;&quot;
+        Clean text from extra spaces and replaces
+        html-entities by unicode symbols
+    &quot;&quot;&quot;
+    text = text.strip().replace(u'\n', u'').replace(u'\r', u'')
+    return ENTITY_CONVERTER.sub(_convertentity, text)
+
+
+
+
+def _img_from_text(text, font, size=12, color='#000', decoration={}):
+    &quot;&quot;&quot;
+        Draws text with font, size, color and decoration parameters.
+        Caches images and returns (html or object, width, size) of
+        new or exists image
+    &quot;&quot;&quot;
+    
+    image_path = path.join(settings.MEDIA_ROOT, HEADLINE_CACHE_DIR)
+    font_path = path.join(settings.MEDIA_ROOT, HEADLINE_FONTS_DIR)
+
+    id = &quot;headline-%s&quot; % md5(smart_str(''.join((text, font, size.__str__(), color, decoration.__str__())))).hexdigest()
+    image_file = path.join(image_path, &quot;%s.png&quot; % id)
+    
+
+    if not path.isfile(image_file) or HEADLINE_NO_CACHE:
+        
+        size = int(size)
+        font = ImageFont.truetype(path.join(font_path, font), size)
+        width, height = font.getsize(text)
+        
+        ### Init surfaces
+        image = Image.new(&quot;RGB&quot;, (width, height), (0,0,0))
+        alpha = Image.new(&quot;L&quot;, image.size, &quot;black&quot;)
+        imtext = Image.new(&quot;L&quot;, image.size, 0)
+        draw = ImageDraw.Draw(imtext)
+        
+        ### Real Drawings on alpha with white color
+        if decoration.has_key('opacity'):
+            opacity = float(decoration['opacity']) * 255
+        else:
+            opacity = 255
+            
+        ### Draws text
+        draw.text((0, 0), text, font=font, fill=opacity)
+        
+        ### Draws an underline
+        if decoration.has_key('underline'):
+            val = int(decoration['underline'])
+            draw.line((0 + size/20, height * 4 / 5 + val,
+                       width - size/20, height * 4 / 5 + val),
+                       fill=opacity, width=size / 20)
+        
+        ### Draws an strikeout line
+        if decoration.has_key('strikeout'):
+            val = int(decoration['strikeout'])
+            draw.line((0 + size/20, height / 2  + val,
+                       width - size/20, height / 2  + val),
+                       fill=opacity, width=size / 20)
+            
+        ### Alpha color black-magic
+        alpha = ImageChops.lighter(alpha, imtext)
+        solidcolor = Image.new(&quot;RGBA&quot;, image.size, color)
+        immask = Image.eval(imtext, lambda p: 255 * (int(p != 0)))
+        image = Image.composite(solidcolor, image, immask)
+        image.putalpha(alpha)
+        
+        ### Rotation
+        if decoration.has_key('rotate') and decoration['rotate']:
+            angle = float(decoration['rotate'])
+            if angle == 90:
+                image = image.transpose(Image.ROTATE_90)
+            elif angle == 180:
+                image = image.transpose(Image.ROTATE_180)
+            elif angle == 270:
+                image = image.transpose(Image.ROTATE_270)
+            else:
+                # XXX: Bad rotation
+                # Really bicubic transformation works only
+                # when canvas doesn`t resize: last param is False
+                image = image.rotate(angle, Image.BICUBIC, True)
+            width, height = image.size
+        
+        ### Save image
+        image.save(image_file, &quot;PNG&quot;)
+        
+        ### Optimize png with external tool
+        if HEADLINE_PNG_OPTIMIZER:
+            from os import system
+            system(HEADLINE_PNG_OPTIMIZER % {&quot;file&quot;: image_file})
+        
+    else:
+        ### We need just dimentions
+        width, height = Image.open(image_file).size
+        
+    return &quot;%s%s/%s.png&quot; % \
+           (settings.MEDIA_URL, HEADLINE_CACHE_DIR, id), width, height
+
+
+
+def _image_list(output, klass, splitter, object=False):
+    &quot;&quot;&quot;
+        Pictures and html or objects generator by split options
+    &quot;&quot;&quot;
+    if splitter:
+        chunks = splitter.split(output)
+    else:
+        chunks = (output, )
+        
+    for text in chunks:
+        text = _clean_text(text)
+        if not text: continue
+        
+        url, width, height = _img_from_text(text, **klass)
+        obj = { 'text': text,
+                'url': url,
+                'width': width,
+                'height': height }
+            
+        if object:
+            yield obj
+        else:
+            yield HEADLINE_TEMPLATE % obj
+    
+    
+
+def _create_splitter(splitting):
+    &quot;&quot;&quot;
+        Creates regular expression text splitter
+    &quot;&quot;&quot;
+    if splitting == 'br':
+        return re.compile(r&quot;&lt;br */?&gt;&quot;), &quot;&lt;br /&gt;&quot;
+    elif splitting == 'all':
+        return re.compile(r&quot;&lt;br */?&gt;| *&quot;), &quot; &quot;
+    else:
+        return False, &quot;&quot;
+
+
+
+def _get_class( klass ):
+    &quot;&quot;&quot;
+        Get or create real class parameters by options string
+    &quot;&quot;&quot;
+    params = re.split(r&quot;, *&quot;, klass.strip('&quot;'))
+    cleaned = []
+    klass = False
+    typ = False
+
+    ### If it is render parameters string
+    if len(params) &gt; 2:
+        decoration = {}
+        
+        ### Remove all decorators, they can be anywhere
+        ### and add they into separate dict
+        for param in params:
+            param_unpack = param.split(':')
+            if param_unpack[0] in AVIABLE_DECORATIONS:
+                if len(param_unpack) &gt; 1:
+                    decoration[param_unpack[0]] = param_unpack[1]
+                else:
+                    decoration[param_unpack[0]] = AVIABLE_DECORATIONS[param_unpack[0]]
+            else:
+                cleaned.append(param)
+        
+        if(len(cleaned) &lt; 3):
+            raise TemplateSyntaxError('Headline render parameters string must have at least 3 parameters (excepting decorations): %s' % &quot;,&quot;.join(cleaned))
+        ### There we can have type of splitting too
+        elif len(cleaned) &gt; 3:
+            typ = cleaned[3]
+        
+        klass = {
+            'font': cleaned[0],
+            'size': int(cleaned[1]),
+            'color': cleaned[2],
+            'decoration': decoration
+        }
+        
+    ### If it is class
+    elif params &gt; 0:
+        try:
+            klass = HEADLINE_CLASSES[params[0]]
+        except:
+            raise TemplateSyntaxError('There is no class %s in HEADLINE_CLASSES definition.' % klass)
+        
+        ### Back compatibility with v0.2
+        if isinstance(klass.setdefault('decoration', {}), (list, tuple)):
+            decoration = {}
+            for i in klass['decoration']:
+                decoration[i] = AVIABLE_DECORATIONS[i]
+            klass['decoration'] = decoration
+        
+        ### Type of splitting can be here too
+        if len(params) &gt; 1:
+            typ = params[1]
+        
+    return klass, typ
+
+
+
+register = template.Library()
+
+
+
+@register.filter(name=&quot;headline&quot;)
+def do_text_image_filter(value, klass):
+    '''
+    Django filter, that generates png image with text
+    from variable and returns it`s html representation.
+    
+    Examples:
+       {{ foo|headline:&quot;font.ttf,20,#000&quot; }}
+       {{ foo|headline:&quot;font.ttf,20,#000,underline,all&quot; }}
+       {{ foo|headline:&quot;base,br&quot; }}    
+    '''
+    klass, typ = _get_class(klass)
+    if not klass:
+        raise TemplateSyntaxError('Headline filter needs in single render parameters string' )
+        
+    return mark_safe(TextImageNode(value, klass, typ).render_text())
+
+do_text_image_filter.is_safe = True
+
+
+
+@register.tag(name=&quot;headline&quot;)
+def do_text_image_tag(parser, token):
+    '''
+    Django tag, that generates png image with text
+    from tag inside and returns it`s html representation.
+    
+    Examples:
+        {% headline &quot;font.ttf,20,opacity:0.5,#000&quot; %}Big {{ foo }}{% endheadline %}
+        {% headline &quot;font.ttf,20,#000,strikeout:-5,none&quot; %}Big {{ foo }}{% endheadline %}
+        {% headline &quot;base&quot; %}Big {{ foo }}{% endheadline %} 
+    '''
+    params = token.split_contents()
+    
+    klass, typ = _get_class(params[1])
+        
+    if not klass:
+        raise TemplateSyntaxError('Headline tag needs in single render parameters string' )
+        
+    if not typ:
+        typ = &quot;br&quot;
+    
+    nodelist = parser.parse(('endheadline',))
+    parser.delete_first_token()
+        
+    return TextImageNode(nodelist, klass, typ)
+
+
+
+@register.tag(name=&quot;headlines&quot;)
+def do_text_images_tag(parser, token):
+    '''
+    Django tag, that generates png images with text
+    from tag parameters and returns it`s dict representations
+    into context variable.
+    
+    Examples:
+        {% headlines foo_list bar_dict baz_var &quot;And some text&quot; as headers &quot;font.ttf,20,#000&quot; %}
+        {% headlines foo_list bar_dict baz_var &quot;And some text&quot; as headers &quot;font.ttf,20,#000,all&quot; %}
+        {% headlines foo_list bar_dict baz_var &quot;And some text&quot; as headers &quot;base&quot; %}
+    '''
+    params = token.split_contents()
+        
+    if len(params) &gt; 4 and params[-3] == 'as':
+        klass, typ = _get_class(params[-1])
+        
+        output = []
+        
+        for st in params[1:-3]:
+            ### If it is just a string
+            if st.startswith('&quot;') and st.endswith('&quot;'):
+                output.append(st.strip('&quot;'))
+                
+            ### Else it is context variable
+            else:
+                output.append(parser.compile_filter(st))
+                
+        return TextImagesNode(output, params[-2], klass, typ)
+           
+    else:
+        raise TemplateSyntaxError('Hedlines tag must have at least 4 parameters: one or more variables to render, &quot;as&quot; keyword, context variable and render parameters string. Like this: {% headlines &lt;list of vars&gt; as &lt;context_var&gt; &lt;class_or_params&gt; %}' )
+
+
+
+
+class TextImageNode(template.Node):
+    
+    def __init__(self, nodelist, klass, splitting=&quot;br&quot;):
+        self.klass = klass
+        self.splitter, self.joiner = _create_splitter(splitting)
+        self.nodelist = nodelist
+        
+    def render_text(self):
+        &quot;&quot;&quot; If filter &quot;&quot;&quot;
+        output = self.nodelist
+        return self.joiner.join(
+            _image_list( output, self.klass, self.splitter )
+        )
+        
+    def render(self, context):
+        &quot;&quot;&quot; If tag &quot;&quot;&quot;
+        output = self.nodelist.render(context)
+        return self.joiner.join(
+            _image_list( output, self.klass, self.splitter )
+        )
+
+
+
+class TextImagesNode(template.Node):
+    def __init__(self, output, to, klass, splitting):
+        self.klass = klass
+        self.output = output
+        self.to = to
+        self.splitter, self.joiner = _create_splitter(splitting)
+        
+    def _flatten_data(self, output, context):
+        &quot;&quot;&quot;
+            Generator of images from all-typed parameters
+        &quot;&quot;&quot;
+        ### We walk thu all parameters
+        for token in output:
+            
+            ### Gets just text strings
+            if isinstance(token, (unicode, str)):
+                token = (token, )
+            
+            else:
+                ### And context variables
+                token = token.resolve(context)
+                
+                ### If it single variable we transforms is into list
+                if not isinstance(token, (list, tuple, dict)):
+                    token = (token, )
+                    
+            ### And then ruturns all of them in single stream
+            for tk in token:
+                for obj in _image_list( tk, self.klass, self.splitter, True):
+                    yield obj
+    
+    def render(self, context):
+        context[self.to] = [item for item in self._flatten_data(self.output, context)]
+        return ''</diff>
      <filename>templatetags/headline.py</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>TODO</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>24bd8daa6dc91bcfc5918750b5f61e1131cc9cde</id>
    </parent>
    <parent>
      <id>88adb109ea53e21d93a5af9dc8e57205890a2926</id>
    </parent>
  </parents>
  <author>
    <name>Igor SkAZi Potapov</name>
    <email>igor@plan-b.ru</email>
  </author>
  <url>http://github.com/SkAZi/django-headline/commit/8599e7dd80dd4c5678314550a97053842a8e5612</url>
  <id>8599e7dd80dd4c5678314550a97053842a8e5612</id>
  <committed-date>2009-07-14T23:06:44-07:00</committed-date>
  <authored-date>2009-07-14T23:06:44-07:00</authored-date>
  <message>Merge branch 'unstable'</message>
  <tree>2d73ef5ecf3686e96e3b88a5c001502001a08802</tree>
  <committer>
    <name>Igor SkAZi Potapov</name>
    <email>igor@plan-b.ru</email>
  </committer>
</commit>
