textile_reader.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals, print_function
  3. from pelican import signals
  4. from pelican.readers import BaseReader
  5. from pelican.utils import pelican_open
  6. try:
  7. from textile import textile
  8. except ImportError:
  9. textile = False
  10. class TextileReader(BaseReader):
  11. """Reader for Textile files. Written using the core MarkdownReader as
  12. a template. Textile input files must be of the form:
  13. Title: An example
  14. Date: 2013-08-10
  15. ----
  16. p. Lorem ipsum dolar sit amet...
  17. Specifically, the header values as with Markdown files, then four
  18. dashes, then the body.
  19. """
  20. enabled = bool(textile)
  21. file_extensions = ['textile']
  22. def __init__(self, *args, **kwargs):
  23. super(TextileReader, self).__init__(*args, **kwargs)
  24. def _parse_metadata(self, meta):
  25. """Process the metadata dict, lowercasing the keys and textilizing the
  26. value of the 'summary' key (if present). Keys that share the same
  27. lowercased form will be overridden in some arbitrary order.
  28. """
  29. output = {}
  30. for name, value in meta.items():
  31. name = name.lower()
  32. if name == "summary":
  33. value = textile(value)
  34. output[name] = self.process_metadata(name, value)
  35. return output
  36. def read(self, source_path):
  37. """Parse content and metadata of textile files."""
  38. with pelican_open(source_path) as text:
  39. parts = text.split('----', 1)
  40. if len(parts) == 2:
  41. headerlines = parts[0].splitlines()
  42. headerpairs = map(lambda l: l.split(':', 1), headerlines)
  43. headerdict = {pair[0]: pair[1].strip()
  44. for pair in headerpairs
  45. if len(pair) == 2}
  46. metadata = self._parse_metadata(headerdict)
  47. content = textile(parts[1])
  48. else:
  49. metadata = {}
  50. content = textile(text)
  51. return content, metadata
  52. def add_reader(readers):
  53. readers.reader_classes['textile'] = TextileReader
  54. def register():
  55. signals.readers_init.connect(add_reader)