Index: django/utils/html.py
===================================================================
--- django/utils/html.py	(revision 5883)
+++ django/utils/html.py	(working copy)
@@ -30,12 +30,22 @@
     return force_unicode(html).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
 escape = allow_lazy(escape, unicode)
 
-def linebreaks(value):
-    "Convert newlines into <p> and <br />s."
+def linebreaks(value, paragraph=True, xhtml=True):
+    """
+    Converts newlines into paragraphs (<p>) containing line breaks (<br/>, <br>)
+    Note: Using <br/> instead of <br /> may be less cosmetic but avoids
+    potential stripping bugs from other utils such as truncatewords.
+    """
+    br = '<br/>'
+    if not xhtml:
+        br = '<br>'
     value = re.sub(r'\r\n|\r|\n', '\n', force_unicode(value)) # normalize newlines
-    paras = re.split('\n{2,}', value)
-    paras = [u'<p>%s</p>' % p.strip().replace('\n', '<br />') for p in paras]
-    return u'\n\n'.join(paras)
+    if paragraph:
+        paras = re.split('\n{2,}', value)
+        paras = [u'<p>%s</p>' % p.strip().replace('\n', br) for p in paras]
+        return u'\n\n'.join(paras)
+    else:
+        return  value.strip().replace('\n', br)
 linebreaks = allow_lazy(linebreaks, unicode)
 
 def strip_tags(value):
Index: django/template/defaultfilters.py
===================================================================
--- django/template/defaultfilters.py	(revision 5883)
+++ django/template/defaultfilters.py	(working copy)
@@ -253,15 +253,26 @@
     return escape(value)
 escape = stringfilter(escape)
 
-def linebreaks(value):
-    "Converts newlines into <p> and <br />s"
+def linebreaks(value , arg=""):
+    """
+    Converts newlines into paragraphs and linebreaks. Accepts 'html' as
+    optional parameter; this will return html compliant newlines (<br>)
+    instead of the default xhtml (<br />).
+    """
     from django.utils.html import linebreaks
-    return linebreaks(value)
+    xhtml = (arg != 'html')
+    return linebreaks(value, paragraph=True, xhtml=xhtml)
 linebreaks = stringfilter(linebreaks)
 
-def linebreaksbr(value):
-    "Converts newlines into <br />s"
-    return value.replace('\n', '<br />')
+def linebreaksbr(value, arg=""):
+    """
+    Converts newlines into linebreaks. Accepts 'html' as optional parameter;
+    this will return html compliant newlines (<br>) instead of the default
+    xhtml (<br />).
+    """
+    from django.utils.html import linebreaks
+    xhtml = (arg != 'html')
+    return linebreaks(value, paragraph=False, xhtml=xhtml)
 linebreaksbr = stringfilter(linebreaksbr)
 
 def removetags(value, tags):
Index: tests/regressiontests/utils/tests.py
===================================================================
--- tests/regressiontests/utils/tests.py	(revision 5883)
+++ tests/regressiontests/utils/tests.py	(working copy)
@@ -39,13 +39,14 @@
     def test_linebreaks(self):
         f = html.linebreaks
         items = (
-            ("para1\n\npara2\r\rpara3", "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"),
-            ("para1\nsub1\rsub2\n\npara2", "<p>para1<br />sub1<br />sub2</p>\n\n<p>para2</p>"),
-            ("para1\r\n\r\npara2\rsub1\r\rpara4", "<p>para1</p>\n\n<p>para2<br />sub1</p>\n\n<p>para4</p>"),
-            ("para1\tmore\n\npara2", "<p>para1\tmore</p>\n\n<p>para2</p>"),
+            (("para1\n\npara2\r\rpara3", True, True ), "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"),
+            (("para1\n\npara2\r\rpara3", False, False ), "para1<br><br>para2<br><br>para3"),
+            (("para1\nsub1\rsub2\n\npara2", True, True ), "<p>para1<br/>sub1<br/>sub2</p>\n\n<p>para2</p>"),
+            (("para1\r\n\r\npara2\rsub1\r\rpara4", False, True ), "para1<br/><br/>para2<br/>sub1<br/><br/>para4"),
+            (("para1\tmore\n\npara2", True, False), "<p>para1\tmore</p>\n\n<p>para2</p>"),
         )
         for value, output in items:
-            self.check_output(f, value, output)
+            self.assertEqual(f(value[0],paragraph=value[1],xhtml=value[2]),output)
 
     def test_strip_tags(self):
         f = html.strip_tags
Index: tests/regressiontests/defaultfilters/tests.py
===================================================================
--- tests/regressiontests/defaultfilters/tests.py	(revision 5883)
+++ tests/regressiontests/defaultfilters/tests.py	(working copy)
@@ -200,8 +200,11 @@
 u'<p>line 1</p>'
 
 >>> linebreaks(u'line 1\nline 2')
-u'<p>line 1<br />line 2</p>'
+u'<p>line 1<br/>line 2</p>'
 
+>>> linebreaks(u'line 1\nline 2', "html")
+u'<p>line 1<br>line 2</p>'
+
 >>> removetags(u'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img')
 u'some <b>html</b> with alert("You smell") disallowed  tags'
 
@@ -467,6 +470,12 @@
 u'<p>123</p>'
 >>> linebreaksbr(123)
 u'123'
+>>> linebreaksbr('123\n123')
+u'123<br/>123'
+>>> linebreaksbr('123\n123',"bad syntax")
+u'123<br/>123'
+>>> linebreaksbr('123\n123',"html")
+u'123<br>123'
 >>> removetags(123, 'a')
 u'123'
 >>> striptags(123)
Index: docs/templates.txt
===================================================================
--- docs/templates.txt	(revision 5883)
+++ docs/templates.txt	(working copy)
@@ -1118,13 +1118,18 @@
 linebreaks
 ~~~~~~~~~~
 
-Converts newlines into ``<p>`` and ``<br />`` tags.
+Converts newlines into paragraphs ``<p>`` containing line breaks ``<br/>``,
+``<br>``.
 
+**Argument:** ``'html'`` will result in html compliant output. 
+
 linebreaksbr
 ~~~~~~~~~~~~
 
-Converts newlines into ``<br />`` tags.
+Converts newlines into ``<br/>``, ``<br>`` tags.
 
+**Argument:** ``'html'`` will result in html compliant output. 
+
 linenumbers
 ~~~~~~~~~~~
 
