If you're like me and write web documents often then you prefer to type the markup and styling by hand instead of a pseudo-HTML language or something like Textitle. However I do like it when the simple things are handled automatically. It gets annoying typing <br> or <p> constantly all over each document, and it makes it a pain to read also.
I use Django's linebreaks template filter a lot because it takes care of all that. I can just type naturally and paragraphs and linebreaks are automatically inserted into the HTML output. However it causes an issue when I do want to insert HTML block elements such as <div> or <blockquote>. To remedy this I took their source code and rewrote part of it.
If you haven't already, you should check out Django's guide to adding custom template filters. Note also that my source code is optimized for HTML4 output rather than XHTML. You can change this yourself easily by just adding end tags where appropriate.
import re
from django import template
from django.utils.functional import allow_lazy
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe, SafeData
from django.utils.encoding import force_unicode
from django.utils.html import escape
register = template.Library()
def linebreaks_smart_function(value, autoescape=False):
BLOCK_ELEMENTS = ['p','div','blockquote','ul','ol'] # these are just ones I use often. Feel free to add your own!
value = re.sub(r'\r\n|\r|\n', '\n', force_unicode(value)) # normalize newlines
paras = re.split('\n{2,}', value)
parsedParas = []
if autoescape:
for p in paras:
if re.match("<"+">|<".join(BLOCK_ELEMENTS) + ">", p):
parsedParas.append(escape(p.strip()).replace('\n', '<br>'))
else:
parsedParas.append(u'<p>%s' % escape(p.strip()).replace('\n', '<br>'))
else:
for p in paras:
if re.match("<"+">|<".join(BLOCK_ELEMENTS) + ">", p):
parsedParas.append(p.replace('\n', '<br>'))
else:
parsedParas.append(u'<p>%s' % p.strip().replace('\n', '<br>'))
return u'\n\n'.join(parsedParas)
linebreaks_smart_function = allow_lazy(linebreaks_smart_function_util, unicode)
@register.filter
def linebreaks_smart(value, autoescape=None):
"""
Replaces line breaks in plain text with appropriate HTML; a single
newline becomes an HTML line break (<br>) and a new line
followed by a blank line becomes a paragraph break (<p>).
Paragraphs beginning with an HTML block element (<div>) are not
turned into HTML paragraphs.
"""
autoescape = autoescape and not isinstance(value, SafeData)
return mark_safe(linebreaks_smart_function(value, autoescape))
linebreaks_smart.is_safe = True
linebreaks_smart.needs_autoescape = True
linebreaks_smart = stringfilter(linebreaks_smart)
Once you have this code copied simply put linebreaks_smart in your template like so: {{ examplePost|linebreaks_smart }}. Enjoy!
This text box does not actually do anything. However if you feel an overwhelming urge to express yourself you may go ahead and type in it. If you want to talk to my personally use my contact information.