wikilinks.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. '''
  2. WikiLinks Extension for Python-Markdown
  3. ======================================
  4. Converts [[WikiLinks]] to relative links.
  5. See <https://Python-Markdown.github.io/extensions/wikilinks>
  6. for documentation.
  7. Original code Copyright [Waylan Limberg](http://achinghead.com/).
  8. All changes Copyright The Python Markdown Project
  9. License: [BSD](https://opensource.org/licenses/bsd-license.php)
  10. '''
  11. from . import Extension
  12. from ..inlinepatterns import InlineProcessor
  13. import xml.etree.ElementTree as etree
  14. import re
  15. def build_url(label, base, end):
  16. """ Build a url from the label, a base, and an end. """
  17. clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label)
  18. return '{}{}{}'.format(base, clean_label, end)
  19. class WikiLinkExtension(Extension):
  20. def __init__(self, **kwargs):
  21. self.config = {
  22. 'base_url': ['/', 'String to append to beginning or URL.'],
  23. 'end_url': ['/', 'String to append to end of URL.'],
  24. 'html_class': ['wikilink', 'CSS hook. Leave blank for none.'],
  25. 'build_url': [build_url, 'Callable formats URL from label.'],
  26. }
  27. super().__init__(**kwargs)
  28. def extendMarkdown(self, md):
  29. self.md = md
  30. # append to end of inline patterns
  31. WIKILINK_RE = r'\[\[([\w0-9_ -]+)\]\]'
  32. wikilinkPattern = WikiLinksInlineProcessor(WIKILINK_RE, self.getConfigs())
  33. wikilinkPattern.md = md
  34. md.inlinePatterns.register(wikilinkPattern, 'wikilink', 75)
  35. class WikiLinksInlineProcessor(InlineProcessor):
  36. def __init__(self, pattern, config):
  37. super().__init__(pattern)
  38. self.config = config
  39. def handleMatch(self, m, data):
  40. if m.group(1).strip():
  41. base_url, end_url, html_class = self._getMeta()
  42. label = m.group(1).strip()
  43. url = self.config['build_url'](label, base_url, end_url)
  44. a = etree.Element('a')
  45. a.text = label
  46. a.set('href', url)
  47. if html_class:
  48. a.set('class', html_class)
  49. else:
  50. a = ''
  51. return a, m.start(0), m.end(0)
  52. def _getMeta(self):
  53. """ Return meta data or config data. """
  54. base_url = self.config['base_url']
  55. end_url = self.config['end_url']
  56. html_class = self.config['html_class']
  57. if hasattr(self.md, 'Meta'):
  58. if 'wiki_base_url' in self.md.Meta:
  59. base_url = self.md.Meta['wiki_base_url'][0]
  60. if 'wiki_end_url' in self.md.Meta:
  61. end_url = self.md.Meta['wiki_end_url'][0]
  62. if 'wiki_html_class' in self.md.Meta:
  63. html_class = self.md.Meta['wiki_html_class'][0]
  64. return base_url, end_url, html_class
  65. def makeExtension(**kwargs): # pragma: no cover
  66. return WikiLinkExtension(**kwargs)