__init__.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. from misago.markdown.factory import *
  2. # Monkeypatch blockquote parser to handle codes
  3. from markdown import util
  4. import markdown.blockprocessors
  5. from markdown.extensions.fenced_code import FENCED_BLOCK_RE, CODE_WRAP, LANG_TAG
  6. class MisagoBlockQuoteProcessor(markdown.blockprocessors.BlockQuoteProcessor):
  7. def run(self, parent, blocks):
  8. block = blocks.pop(0)
  9. m = self.RE.search(block)
  10. if m:
  11. before = block[:m.start()] # Lines before blockquote
  12. # Pass lines before blockquote in recursively for parsing forst.
  13. self.parser.parseBlocks(parent, [before])
  14. # Remove ``> `` from begining of each line.
  15. block = '\n'.join([self.clean(line) for line in
  16. block[m.start():].split('\n')])
  17. sibling = self.lastChild(parent)
  18. if sibling and sibling.tag == "blockquote":
  19. # Previous block was a blockquote so set that as this blocks parent
  20. quote = sibling
  21. else:
  22. # This is a new blockquote. Create a new parent element.
  23. quote = util.etree.SubElement(parent, 'blockquote')
  24. # Recursively parse block with blockquote as parent.
  25. # change parser state so blockquotes embedded in lists use p tags
  26. self.parser.state.set('blockquote')
  27. # MONKEYPATCH START
  28. block = self.clear_codes(block)
  29. # MONKEYPATCH END
  30. self.parser.parseChunk(quote, block)
  31. self.parser.state.reset()
  32. # MONKEYPATCH START
  33. def clear_codes(self, text):
  34. while 1:
  35. m = FENCED_BLOCK_RE.search(text)
  36. if m:
  37. lang = ''
  38. if m.group('lang'):
  39. lang = LANG_TAG % m.group('lang')
  40. code = CODE_WRAP % (lang, self._escape(m.group('code')))
  41. placeholder = self.parser.markdown.htmlStash.store(code, safe=True)
  42. text = '%s\n\n%s\n\n%s' % (text[:m.start()].strip(), placeholder.strip(), text[m.end():].strip())
  43. else:
  44. break
  45. return text.strip()
  46. def _escape(self, txt):
  47. """ basic html escaping """
  48. txt = txt.replace('&', '&')
  49. txt = txt.replace('<', '&lt;')
  50. txt = txt.replace('>', '&gt;')
  51. txt = txt.replace('"', '&quot;')
  52. return txt.strip()
  53. # MONKEYPATCH END
  54. markdown.blockprocessors.BlockQuoteProcessor = MisagoBlockQuoteProcessor