from django.template import Library from django.utils.encoding import force_unicode import re register = Library() re_widont = re.compile(r'\s+(\S+\s*)$') def widont(value, count=1): """ Adds an HTML non-breaking space between the final two words of the string to avoid "widowed" words. Examples: >>> print widont('Test me out') Test me out >>> widont('It works with trailing spaces too ') u'It works with trailing spaces too ' >>> print widont('NoEffect') NoEffect """ def replace(matchobj): return u' %s' % matchobj.group(1) for i in range(count): value = re_widont.sub(replace, force_unicode(value)) return value re_widont_html = re.compile(r'([^<>\s])\s+([^<>\s]+\s*)(]*>|$)', re.IGNORECASE) def widont_html(value): """ Adds an HTML non-breaking space between the final two words at the end of (and in sentences just outside of) block level tags to avoid "widowed" words. Examples: >>> print widont_html('

Here is a simple example

Single

')

Here is a simple example

Single

>>> print widont_html('

test me
out

Ok?

Not in a p

and this

')

test me
out

Ok?

Not in a p

and this

>>> print widont_html('leading text

test me out

trailing text') leading text

test me out

trailing text """ def replace(matchobj): return u'%s %s%s' % matchobj.groups() return re_widont_html.sub(replace, force_unicode(value)) register.filter(widont) register.filter(widont_html) def _test(): import doctest doctest.testmod() if __name__ == "__main__": _test()