meta.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """
  2. Meta Data Extension for Python-Markdown
  3. =======================================
  4. This extension adds Meta Data handling to markdown.
  5. See <https://Python-Markdown.github.io/extensions/meta_data>
  6. for documentation.
  7. Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
  8. All changes Copyright 2008-2014 The Python Markdown Project
  9. License: [BSD](https://opensource.org/licenses/bsd-license.php)
  10. """
  11. from . import Extension
  12. from ..preprocessors import Preprocessor
  13. import re
  14. import logging
  15. log = logging.getLogger('MARKDOWN')
  16. # Global Vars
  17. META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
  18. META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
  19. BEGIN_RE = re.compile(r'^-{3}(\s.*)?')
  20. END_RE = re.compile(r'^(-{3}|\.{3})(\s.*)?')
  21. class MetaExtension (Extension):
  22. """ Meta-Data extension for Python-Markdown. """
  23. def extendMarkdown(self, md):
  24. """ Add MetaPreprocessor to Markdown instance. """
  25. md.registerExtension(self)
  26. self.md = md
  27. md.preprocessors.register(MetaPreprocessor(md), 'meta', 27)
  28. def reset(self):
  29. self.md.Meta = {}
  30. class MetaPreprocessor(Preprocessor):
  31. """ Get Meta-Data. """
  32. def run(self, lines):
  33. """ Parse Meta-Data and store in Markdown.Meta. """
  34. meta = {}
  35. key = None
  36. if lines and BEGIN_RE.match(lines[0]):
  37. lines.pop(0)
  38. while lines:
  39. line = lines.pop(0)
  40. m1 = META_RE.match(line)
  41. if line.strip() == '' or END_RE.match(line):
  42. break # blank line or end of YAML header - done
  43. if m1:
  44. key = m1.group('key').lower().strip()
  45. value = m1.group('value').strip()
  46. try:
  47. meta[key].append(value)
  48. except KeyError:
  49. meta[key] = [value]
  50. else:
  51. m2 = META_MORE_RE.match(line)
  52. if m2 and key:
  53. # Add another line to existing key
  54. meta[key].append(m2.group('value').strip())
  55. else:
  56. lines.insert(0, line)
  57. break # no meta data - done
  58. self.md.Meta = meta
  59. return lines
  60. def makeExtension(**kwargs): # pragma: no cover
  61. return MetaExtension(**kwargs)