Skip to content

Commit

Permalink
Don't linkify text with .py filenames in markdown (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
jace committed Jul 18, 2020
1 parent 0f90bd6 commit 0f61bee
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
11 changes: 9 additions & 2 deletions coaster/utils/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@
from markupsafe import Markup
from pymdownx.emoji import to_alt as emoji_to_alt

from .text import VALID_TAGS, normalize_spaces_multiline, sanitize_html
from .text import (
LINKIFY_CALLBACKS,
LINKIFY_SKIP_TAGS,
VALID_TAGS,
normalize_spaces_multiline,
sanitize_html,
)

__all__ = ['markdown', 'MARKDOWN_HTML_TAGS']

Expand Down Expand Up @@ -157,6 +163,7 @@ def markdown(text, html=False, valid_tags=None):
extensions=extensions_text,
extension_configs=extension_configs,
).convert(text),
skip_tags=['pre'],
callbacks=LINKIFY_CALLBACKS,
skip_tags=LINKIFY_SKIP_TAGS,
)
)
26 changes: 25 additions & 1 deletion coaster/utils/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

__all__ = [
'VALID_TAGS',
'LINKIFY_SKIP_TAGS',
'LINKIFY_CALLBACKS',
'deobfuscate_email',
'normalize_spaces',
'normalize_spaces_multiline',
Expand Down Expand Up @@ -119,6 +121,26 @@
'ul': [],
}

LINKIFY_SKIP_TAGS = ['pre', 'code', 'kbd', 'samp', 'var']


# Adapted from https://bleach.readthedocs.io/en/latest/linkify.html#preventing-links
def dont_linkify_filenames(attrs, new=False):
# This is an existing link, so leave it be
if not new:
return attrs
# If the TLD is '.py', make sure it starts with http: or https:.
# Use _text because that's the original text
link_text = attrs['_text']
if link_text.endswith('.py') and not link_text.startswith(('http:', 'https:')):
# This looks like a Python file, not a URL. Don't make a link.
return None
# Everything checks out, keep going to the next callback.
return attrs


LINKIFY_CALLBACKS = list(DEFAULT_CALLBACKS) + [dont_linkify_filenames]


def sanitize_html(value, valid_tags=None, strip=True, linkify=False):
"""
Expand All @@ -128,7 +150,9 @@ def sanitize_html(value, valid_tags=None, strip=True, linkify=False):
valid_tags = VALID_TAGS
if linkify:
filters = [
partial(LinkifyFilter, skip_tags=['pre'], callbacks=DEFAULT_CALLBACKS)
partial(
LinkifyFilter, callbacks=LINKIFY_CALLBACKS, skip_tags=LINKIFY_SKIP_TAGS
)
]
else:
filters = []
Expand Down
14 changes: 11 additions & 3 deletions tests/test_utils_markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
6. Symbols (ignored): (tm) (c) (r) c/o
7. Symbols (converted): +/- --> <-- <--> =/= 1/2 1/4 1st 2nd 3rd 4th 42nd
An [inline link](https://www.example.com/)
A naked link: https://www.example.com/
An [inline link](https://www.example.com/)
Un-prefixed naked links: hasgeek.in python.py
Python/Paraguay link, prefixed: http://python.py
```python hl_lines="1"
def foo():
Expand Down Expand Up @@ -68,8 +72,10 @@ def foo():
<li>Symbols (ignored): (tm) (c) (r) c/o</li>
<li>Symbols (converted): ± → ← ↔ ≠ ½ ¼ 1<sup>st</sup> 2<sup>nd</sup> 3<sup>rd</sup> 4<sup>th</sup> 42<sup>nd</sup></li>
</ol>
<p>A naked link: <a href="https://www.example.com/" rel="nofollow">https://www.example.com/</a></p>
<p>An <a href="https://www.example.com/" rel="nofollow">inline link</a></p>
<p>A naked link: <a href="https://www.example.com/" rel="nofollow">https://www.example.com/</a></p>
<p>Un-prefixed naked links: <a href="http://hasgeek.in" rel="nofollow">hasgeek.in</a> python.py</p>
<p>Python/Paraguay link, prefixed: <a href="http://python.py" rel="nofollow">http://python.py</a></p>
<div class="highlight"><pre><span></span><code><span class="hll"><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
</span> <span class="k">return</span> <span class="s1">'https://www.example.com/'</span>
</code></pre></div>
Expand Down Expand Up @@ -133,8 +139,10 @@ def foo():
<li>Symbols (ignored): (tm) (c) (r) c/o</li>
<li>Symbols (converted): &plusmn; &rarr; &larr; &harr; &ne; &frac12; &frac14; 1<sup>st</sup> 2<sup>nd</sup> 3<sup>rd</sup> 4<sup>th</sup> 42<sup>nd</sup></li>
</ol>
<p>A naked link: <a href="https://www.example.com/" rel="nofollow">https://www.example.com/</a></p>
<p>An <a href="https://www.example.com/" rel="nofollow">inline link</a></p>
<p>A naked link: <a href="https://www.example.com/" rel="nofollow">https://www.example.com/</a></p>
<p>Un-prefixed naked links: <a href="http://hasgeek.in" rel="nofollow">hasgeek.in</a> python.py</p>
<p>Python/Paraguay link, prefixed: <a href="http://python.py" rel="nofollow">http://python.py</a></p>
<pre><code>def foo():
return &#39;https://www.example.com/&#39;
</code></pre>
Expand Down

0 comments on commit 0f61bee

Please sign in to comment.