Repository: encode/django-rest-framework

Issue:
YAMLRenderer with BrowsableAPIRenderer produces bad links
Considering the following yaml output:

```
{daps: 'http://127.0.0.1:8000/api/daps/', metadaps: 'http://127.0.0.1:8000/api/metadaps/',  users: 'http://127.0.0.1:8000/api/users/'}
```

While the first two URLs works fine, the last one is interpreted as follows:

```
...users: &#39;<a href="http://127.0.0.1:8000/api/users/&#39;%7D" rel="nofollow">http://127.0.0.1:8000/api/users/&#39;}</a>
```

Instead of:

```
...users: &#39;<a href="http://127.0.0.1:8000/api/users/" rel="nofollow">http://127.0.0.1:8000/api/users/</a>&#39;}
```

(The ending quote and brackets are in the link.) Happens basically on any last URL in a bracket, except sometimes the bracket is in the link and sometimes only the `'` sign.

```
dap_set: ['http://127.0.0.1:8000/api/daps/2/']
```

Goes to:

```
dap_set: [&#39;<a href="http://127.0.0.1:8000/api/daps/2/&#39;" rel="nofollow">http://127.0.0.1:8000/api/daps/2/&#39;</a>]
```

Instead if:

```
dap_set: [&#39;<a href="http://127.0.0.1:8000/api/daps/2/" rel="nofollow">http://127.0.0.1:8000/api/daps/2/</a>&#39;]
```

Happens on djangorestframework-2.3.13 with the following settings:

```
REST_FRAMEWORK = {
    # ...
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.YAMLRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
    # ...
}
```



Discussion:
BTW it makes the browsable API almost unbrowsable.


Resolving patch:
diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py
--- a/rest_framework/templatetags/rest_framework.py
+++ b/rest_framework/templatetags/rest_framework.py
@@ -180,7 +180,7 @@ def add_class(value, css_class):
 
 
 # Bunch of stuff cloned from urlize
-TRAILING_PUNCTUATION = ['.', ',', ':', ';', '.)', '"', "'"]
+TRAILING_PUNCTUATION = ['.', ',', ':', ';', '.)', '"', "']", "'}", "'"]
 WRAPPING_PUNCTUATION = [('(', ')'), ('<', '>'), ('[', ']'), ('&lt;', '&gt;'),
                         ('"', '"'), ("'", "'")]
 word_split_re = re.compile(r'(\s+)')


Test patch:
diff --git a/rest_framework/tests/test_urlizer.py b/rest_framework/tests/test_urlizer.py
new file mode 100644
--- /dev/null
+++ b/rest_framework/tests/test_urlizer.py
@@ -0,0 +1,38 @@
+from __future__ import unicode_literals
+from django.test import TestCase
+from rest_framework.templatetags.rest_framework import urlize_quoted_links
+import sys
+
+
+class URLizerTests(TestCase):
+    """
+    Test if both JSON and YAML URLs are transformed into links well
+    """
+    def _urlize_dict_check(self, data):
+        """
+        For all items in dict test assert that the value is urlized key
+        """
+        for original, urlized in data.items():
+            assert urlize_quoted_links(original, nofollow=False) == urlized
+
+    def test_json_with_url(self):
+        """
+        Test if JSON URLs are transformed into links well
+        """
+        data = {}
+        data['"url": "http://api/users/1/", '] = \
+            '&quot;url&quot;: &quot;<a href="http://api/users/1/">http://api/users/1/</a>&quot;, '
+        data['"foo_set": [\n    "http://api/foos/1/"\n], '] = \
+            '&quot;foo_set&quot;: [\n    &quot;<a href="http://api/foos/1/">http://api/foos/1/</a>&quot;\n], '
+        self._urlize_dict_check(data)
+
+    def test_yaml_with_url(self):
+        """
+        Test if YAML URLs are transformed into links well
+        """
+        data = {}
+        data['''{users: 'http://api/users/'}'''] = \
+            '''{users: &#39;<a href="http://api/users/">http://api/users/</a>&#39;}'''
+        data['''foo_set: ['http://api/foos/1/']'''] = \
+            '''foo_set: [&#39;<a href="http://api/foos/1/">http://api/foos/1/</a>&#39;]'''
+        self._urlize_dict_check(data)