/wiki/plugins/links/mdx/urlize.py

https://gitlab.com/rshipp/django-wiki · Python · 104 lines · 77 code · 12 blank · 15 comment · 0 complexity · ba8e9d1a72fac621c39d743cb0824db0 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. """
  3. Code modified from:
  4. https://github.com/r0wb0t/markdown-urlize
  5. A more liberal autolinker
  6. Inspired by Django's urlize function.
  7. Positive examples:
  8. >>> import markdown
  9. >>> md = markdown.Markdown(extensions=['urlize'])
  10. >>> md.convert('http://example.com/')
  11. u'<p><a href="http://example.com/">http://example.com/</a></p>'
  12. >>> md.convert('go to http://example.com')
  13. u'<p>go to <a href="http://example.com">http://example.com</a></p>'
  14. >>> md.convert('example.com')
  15. u'<p><a href="http://example.com">example.com</a></p>'
  16. >>> md.convert('example.net')
  17. u'<p><a href="http://example.net">example.net</a></p>'
  18. >>> md.convert('www.example.us')
  19. u'<p><a href="http://www.example.us">www.example.us</a></p>'
  20. >>> md.convert('(www.example.us/path/?name=val)')
  21. u'<p>(<a href="http://www.example.us/path/?name=val">www.example.us/path/?name=val</a>)</p>'
  22. >>> md.convert('go to <http://example.com> now!')
  23. u'<p>go to <a href="http://example.com">http://example.com</a> now!</p>'
  24. Negative examples:
  25. >>> md.convert('del.icio.us')
  26. u'<p>del.icio.us</p>'
  27. """
  28. import markdown
  29. import re
  30. # Taken from Django trunk 2f121dfe635b3f497fe1fe03bc8eb97cdf5083b3
  31. # https://github.com/django/django/blob/master/django/core/validators.py#L47
  32. URLIZE_RE = (
  33. r'((?:(?:http|ftp)s?://|www\.)' # http:// or https://
  34. r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain...
  35. r'localhost|' # localhost...
  36. r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4
  37. r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6
  38. r'(?::\d+)?' # optional port
  39. r'(?:/[^\s\[\(\]\)]*(?:\s+|$))?)'
  40. )
  41. class UrlizePattern(markdown.inlinepatterns.Pattern):
  42. def __init__(self, pattern, markdown_instance=None):
  43. markdown.inlinepatterns.Pattern.__init__(self, pattern, markdown_instance=markdown_instance)
  44. self.compiled_re = re.compile("^(.*?)%s(.*?)$" % pattern,
  45. re.DOTALL | re.UNICODE | re.IGNORECASE)
  46. """ Return a link Element given an autolink (`http://example/com`). """
  47. def handleMatch(self, m):
  48. url = m.group(2)
  49. if url.startswith('<'):
  50. url = url[1:-1]
  51. text = url
  52. if not url.split('://')[0] in ('http','https','ftp'):
  53. if '@' in url and not '/' in url:
  54. url = 'mailto:' + url
  55. else:
  56. url = 'http://' + url
  57. icon = markdown.util.etree.Element("span")
  58. icon.set('class', 'icon-external-link')
  59. span_text = markdown.util.etree.Element("span")
  60. span_text.text = markdown.util.AtomicString(" " + text)
  61. el = markdown.util.etree.Element("a")
  62. el.set('href', url)
  63. el.set('target', '_blank')
  64. el.append(icon)
  65. el.append(span_text)
  66. return el
  67. class UrlizeExtension(markdown.Extension):
  68. """ Urlize Extension for Python-Markdown. """
  69. def extendMarkdown(self, md, md_globals):
  70. """ Replace autolink with UrlizePattern """
  71. md.inlinePatterns['autolink'] = UrlizePattern(URLIZE_RE, md)
  72. def makeExtension(configs=None):
  73. return UrlizeExtension(configs=configs)
  74. if __name__ == "__main__":
  75. import doctest
  76. doctest.testmod()