Code

Ticket #4573: django-linebreaks-html-v4.diff

File django-linebreaks-html-v4.diff, 5.6 KB (added by Johan Bergström <bugs@…>, 7 years ago)

Fourth revision of the patch

Line 
1Index: django/utils/html.py
2===================================================================
3--- django/utils/html.py        (revision 5883)
4+++ django/utils/html.py        (working copy)
5@@ -30,12 +30,22 @@
6     return force_unicode(html).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
7 escape = allow_lazy(escape, unicode)
8 
9-def linebreaks(value):
10-    "Convert newlines into <p> and <br />s."
11+def linebreaks(value, paragraph=True, xhtml=True):
12+    """
13+    Converts newlines into paragraphs (<p>) containing line breaks (<br/>, <br>)
14+    Note: Using <br/> instead of <br /> may be less cosmetic but avoids
15+    potential stripping bugs from other utils such as truncatewords.
16+    """
17+    br = '<br/>'
18+    if not xhtml:
19+        br = '<br>'
20     value = re.sub(r'\r\n|\r|\n', '\n', force_unicode(value)) # normalize newlines
21-    paras = re.split('\n{2,}', value)
22-    paras = [u'<p>%s</p>' % p.strip().replace('\n', '<br />') for p in paras]
23-    return u'\n\n'.join(paras)
24+    if paragraph:
25+        paras = re.split('\n{2,}', value)
26+        paras = [u'<p>%s</p>' % p.strip().replace('\n', br) for p in paras]
27+        return u'\n\n'.join(paras)
28+    else:
29+        return  value.strip().replace('\n', br)
30 linebreaks = allow_lazy(linebreaks, unicode)
31 
32 def strip_tags(value):
33Index: django/template/defaultfilters.py
34===================================================================
35--- django/template/defaultfilters.py   (revision 5883)
36+++ django/template/defaultfilters.py   (working copy)
37@@ -253,15 +253,26 @@
38     return escape(value)
39 escape = stringfilter(escape)
40 
41-def linebreaks(value):
42-    "Converts newlines into <p> and <br />s"
43+def linebreaks(value , arg=""):
44+    """
45+    Converts newlines into paragraphs and linebreaks. Accepts 'html' as
46+    optional parameter; this will return html compliant newlines (<br>)
47+    instead of the default xhtml (<br />).
48+    """
49     from django.utils.html import linebreaks
50-    return linebreaks(value)
51+    xhtml = (arg != 'html')
52+    return linebreaks(value, paragraph=True, xhtml=xhtml)
53 linebreaks = stringfilter(linebreaks)
54 
55-def linebreaksbr(value):
56-    "Converts newlines into <br />s"
57-    return value.replace('\n', '<br />')
58+def linebreaksbr(value, arg=""):
59+    """
60+    Converts newlines into linebreaks. Accepts 'html' as optional parameter;
61+    this will return html compliant newlines (<br>) instead of the default
62+    xhtml (<br />).
63+    """
64+    from django.utils.html import linebreaks
65+    xhtml = (arg != 'html')
66+    return linebreaks(value, paragraph=False, xhtml=xhtml)
67 linebreaksbr = stringfilter(linebreaksbr)
68 
69 def removetags(value, tags):
70Index: tests/regressiontests/utils/tests.py
71===================================================================
72--- tests/regressiontests/utils/tests.py        (revision 5883)
73+++ tests/regressiontests/utils/tests.py        (working copy)
74@@ -39,13 +39,14 @@
75     def test_linebreaks(self):
76         f = html.linebreaks
77         items = (
78-            ("para1\n\npara2\r\rpara3", "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"),
79-            ("para1\nsub1\rsub2\n\npara2", "<p>para1<br />sub1<br />sub2</p>\n\n<p>para2</p>"),
80-            ("para1\r\n\r\npara2\rsub1\r\rpara4", "<p>para1</p>\n\n<p>para2<br />sub1</p>\n\n<p>para4</p>"),
81-            ("para1\tmore\n\npara2", "<p>para1\tmore</p>\n\n<p>para2</p>"),
82+            (("para1\n\npara2\r\rpara3", True, True ), "<p>para1</p>\n\n<p>para2</p>\n\n<p>para3</p>"),
83+            (("para1\n\npara2\r\rpara3", False, False ), "para1<br><br>para2<br><br>para3"),
84+            (("para1\nsub1\rsub2\n\npara2", True, True ), "<p>para1<br/>sub1<br/>sub2</p>\n\n<p>para2</p>"),
85+            (("para1\r\n\r\npara2\rsub1\r\rpara4", False, True ), "para1<br/><br/>para2<br/>sub1<br/><br/>para4"),
86+            (("para1\tmore\n\npara2", True, False), "<p>para1\tmore</p>\n\n<p>para2</p>"),
87         )
88         for value, output in items:
89-            self.check_output(f, value, output)
90+            self.assertEqual(f(value[0],paragraph=value[1],xhtml=value[2]),output)
91 
92     def test_strip_tags(self):
93         f = html.strip_tags
94Index: tests/regressiontests/defaultfilters/tests.py
95===================================================================
96--- tests/regressiontests/defaultfilters/tests.py       (revision 5883)
97+++ tests/regressiontests/defaultfilters/tests.py       (working copy)
98@@ -200,8 +200,11 @@
99 u'<p>line 1</p>'
100 
101 >>> linebreaks(u'line 1\nline 2')
102-u'<p>line 1<br />line 2</p>'
103+u'<p>line 1<br/>line 2</p>'
104 
105+>>> linebreaks(u'line 1\nline 2', "html")
106+u'<p>line 1<br>line 2</p>'
107+
108 >>> removetags(u'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags', 'script img')
109 u'some <b>html</b> with alert("You smell") disallowed  tags'
110 
111@@ -467,6 +470,12 @@
112 u'<p>123</p>'
113 >>> linebreaksbr(123)
114 u'123'
115+>>> linebreaksbr('123\n123')
116+u'123<br/>123'
117+>>> linebreaksbr('123\n123',"bad syntax")
118+u'123<br/>123'
119+>>> linebreaksbr('123\n123',"html")
120+u'123<br>123'
121 >>> removetags(123, 'a')
122 u'123'
123 >>> striptags(123)
124Index: docs/templates.txt
125===================================================================
126--- docs/templates.txt  (revision 5883)
127+++ docs/templates.txt  (working copy)
128@@ -1118,13 +1118,18 @@
129 linebreaks
130 ~~~~~~~~~~
131 
132-Converts newlines into ``<p>`` and ``<br />`` tags.
133+Converts newlines into paragraphs ``<p>`` containing line breaks ``<br/>``,
134+``<br>``.
135 
136+**Argument:** ``'html'`` will result in html compliant output.
137+
138 linebreaksbr
139 ~~~~~~~~~~~~
140 
141-Converts newlines into ``<br />`` tags.
142+Converts newlines into ``<br/>``, ``<br>`` tags.
143 
144+**Argument:** ``'html'`` will result in html compliant output.
145+
146 linenumbers
147 ~~~~~~~~~~~
148