org_reader.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. Org Reader
  3. ==========
  4. Version 1.0.
  5. Relevant Pelican settings:
  6. - ORG_READER_EMACS_LOCATION: Required. Location of Emacs binary.
  7. - ORG_READER_EMACS_SETTINGS: Optional. An absolute path to an Elisp file, to
  8. run per invocation. Useful for initializing the `package` Emacs library if
  9. that's where your Org mode comes from, or any modifications to Org Export-
  10. related variables.
  11. - ORG_READER_BACKEND: Optional. A custom backend to provide to Org. Defaults
  12. to 'html.
  13. To provide metadata to Pelican, provide the following header in your Org file:
  14. #+TITLE: The Title Of This BlogPost
  15. #+DATE: 2001-01-01
  16. #+CATEGORY: comma, separated, list, of, tags
  17. The slug is automatically the filename of the Org file.
  18. """
  19. import os
  20. import json
  21. import logging
  22. import subprocess
  23. from pelican import readers
  24. from pelican import signals
  25. from pelican import settings
  26. ELISP = os.path.join(os.path.dirname(__file__), 'org_reader.el')
  27. LOG = logging.getLogger(__name__)
  28. class OrgReader(readers.BaseReader):
  29. enabled = True
  30. EMACS_ARGS = ["--batch"]
  31. ELISP_EXEC = "(org->pelican \"{0}\" {1})"
  32. file_extensions = ['org']
  33. def __init__(self, settings):
  34. super(OrgReader, self).__init__(settings)
  35. assert 'ORG_READER_EMACS_LOCATION' in self.settings, \
  36. "No ORG_READER_EMACS_LOCATION specified in settings"
  37. def read(self, filename):
  38. LOG.info("Reading Org file {0}".format(filename))
  39. cmd = [self.settings['ORG_READER_EMACS_LOCATION']]
  40. cmd.extend(self.EMACS_ARGS)
  41. if 'ORG_READER_EMACS_SETTINGS' in self.settings:
  42. cmd.append('-l')
  43. cmd.append(self.settings['ORG_READER_EMACS_SETTINGS'])
  44. backend = self.settings.get('ORG_READER_BACKEND', "'html")
  45. cmd.append('-l')
  46. cmd.append(ELISP)
  47. cmd.append('--eval')
  48. cmd.append(self.ELISP_EXEC.format(filename, backend))
  49. LOG.debug("OrgReader: running command `{0}`".format(cmd))
  50. json_result = subprocess.check_output(cmd, universal_newlines=True)
  51. json_output = json.loads(json_result)
  52. slug, e = os.path.splitext(os.path.basename(filename))
  53. metadata = {'title': json_output['title'],
  54. 'tags': json_output['category'] or '',
  55. 'slug': slug,
  56. 'date': json_output['date']}
  57. parsed = {}
  58. for key, value in metadata.items():
  59. parsed[key] = self.process_metadata(key, value)
  60. return json_output['post'], parsed
  61. def add_reader(readers):
  62. readers.reader_classes['org'] = OrgReader
  63. def register():
  64. signals.readers_init.connect(add_reader)