diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
index 60fa59e..7fefb99 100644
a
|
b
|
make_list = stringfilter(make_list)
|
206 | 206 | |
207 | 207 | def slugify(value): |
208 | 208 | """ |
209 | | Normalizes string, converts to lowercase, removes non-alpha characters, |
210 | | and converts spaces to hyphens. |
| 209 | Converts to lowercase, removes non-word characters (alphanumerics and |
| 210 | underscores) and converts spaces to hyphens. Also strips leading and |
| 211 | trailing whitespace. |
211 | 212 | """ |
212 | | import unicodedata |
213 | | value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') |
214 | | value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) |
215 | | return mark_safe(re.sub('[-\s]+', '-', value)) |
| 213 | from django.utils.text import slugify |
| 214 | return slugify(value) |
216 | 215 | slugify.is_safe = True |
217 | 216 | slugify = stringfilter(slugify) |
218 | 217 | |
… |
… |
safeseq.is_safe = True
|
441 | 440 | |
442 | 441 | def removetags(value, tags): |
443 | 442 | """Removes a space separated list of [X]HTML tags from the output.""" |
444 | | tags = [re.escape(tag) for tag in tags.split()] |
445 | | tags_re = u'(%s)' % u'|'.join(tags) |
446 | | starttag_re = re.compile(ur'<%s(/?>|(\s+[^>]*>))' % tags_re, re.U) |
447 | | endtag_re = re.compile(u'</%s>' % tags_re) |
448 | | value = starttag_re.sub(u'', value) |
449 | | value = endtag_re.sub(u'', value) |
450 | | return value |
| 443 | from django.utils.html import remove_tags |
| 444 | return remove_tags(value, tags) |
451 | 445 | removetags.is_safe = True |
452 | 446 | removetags = stringfilter(removetags) |
453 | 447 | |
diff --git a/django/utils/html.py b/django/utils/html.py
index 7fda015..5f90c67 100644
a
|
b
|
def strip_tags(value):
|
84 | 84 | return re.sub(r'<[^>]*?>', '', force_unicode(value)) |
85 | 85 | strip_tags = allow_lazy(strip_tags) |
86 | 86 | |
| 87 | def remove_tags(html, tags): |
| 88 | """Returns the given HTML with given tags removed.""" |
| 89 | tags = [re.escape(tag) for tag in tags.split()] |
| 90 | tags_re = u'(%s)' % u'|'.join(tags) |
| 91 | starttag_re = re.compile(ur'<%s(/?>|(\s+[^>]*>))' % tags_re, re.U) |
| 92 | endtag_re = re.compile(u'</%s>' % tags_re) |
| 93 | html = starttag_re.sub(u'', html) |
| 94 | html = endtag_re.sub(u'', html) |
| 95 | return html |
| 96 | remove_tags = allow_lazy(remove_tags, unicode) |
| 97 | |
87 | 98 | def strip_spaces_between_tags(value): |
88 | 99 | """Returns the given HTML with spaces between tags removed.""" |
89 | 100 | return re.sub(r'>\s+<', '><', force_unicode(value)) |
diff --git a/django/utils/text.py b/django/utils/text.py
index 00c999c..3134928 100644
a
|
b
|
|
1 | 1 | import re |
| 2 | import unicodedata |
| 3 | |
2 | 4 | from django.utils.encoding import force_unicode |
3 | 5 | from django.utils.functional import allow_lazy |
4 | 6 | from django.utils.translation import ugettext_lazy, ugettext as _ |
| 7 | from django.utils.safestring import mark_safe |
| 8 | |
5 | 9 | from htmlentitydefs import name2codepoint |
6 | 10 | |
7 | 11 | # Capitalizes the first letter of a string. |
… |
… |
def unescape_string_literal(s):
|
283 | 287 | quote = s[0] |
284 | 288 | return s[1:-1].replace(r'\%s' % quote, quote).replace(r'\\', '\\') |
285 | 289 | unescape_string_literal = allow_lazy(unescape_string_literal) |
| 290 | |
| 291 | def slugify(value): |
| 292 | """ |
| 293 | Converts to lowercase, removes non-word characters (alphanumerics and |
| 294 | underscores) and converts spaces to hyphens. Also strips leading and |
| 295 | trailing whitespace. |
| 296 | """ |
| 297 | value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') |
| 298 | value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) |
| 299 | return mark_safe(re.sub('[-\s]+', '-', value)) |
| 300 | slugify = allow_lazy(slugify, unicode) |
diff --git a/tests/regressiontests/utils/html.py b/tests/regressiontests/utils/html.py
index d8b9bde..805835d 100644
a
|
b
|
class TestUtilsHtml(unittest.TestCase):
|
133 | 133 | ) |
134 | 134 | for value, output in items: |
135 | 135 | self.check_output(f, value, output) |
| 136 | |
| 137 | def test_remove_tags(self): |
| 138 | f = html.remove_tags |
| 139 | items = ( |
| 140 | ("<b><i>Yes</i></b>", "b i", "Yes"), |
| 141 | ("<a>x</a> <p><b>y</b></p>", "a b", "x <p>y</p>"), |
| 142 | ) |
| 143 | for value, tags, output in items: |
| 144 | self.assertEquals(f(value, tags), output) |
diff --git a/tests/regressiontests/utils/text.py b/tests/regressiontests/utils/text.py
index f565d87..8ca9dca 100644
a
|
b
|
class TestUtilsText(unittest.TestCase):
|
38 | 38 | self.assertEqual(text.wrap(long_word, 20), long_word) |
39 | 39 | self.assertEqual(text.wrap('a %s word' % long_word, 10), |
40 | 40 | u'a\n%s\nword' % long_word) |
| 41 | |
| 42 | def test_slugify(self): |
| 43 | items = ( |
| 44 | (u'Hello, World!', 'hello-world'), |
| 45 | (u'spam & eggs', 'spam-eggs'), |
| 46 | ) |
| 47 | for value, output in items: |
| 48 | self.assertEqual(text.slugify(value), output) |