rmd_reader.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #-*- conding: utf-8 -*-
  2. import os
  3. import warnings
  4. import logging
  5. logger = logging.getLogger(__name__)
  6. from pelican import readers
  7. from pelican import signals
  8. from pelican import settings
  9. from pelican.utils import pelican_open
  10. from markdown import Markdown
  11. knitr = None
  12. rmd = False
  13. def initsignal(pelicanobj):
  14. global knitr,rmd
  15. try:
  16. with warnings.catch_warnings():
  17. warnings.simplefilter("ignore")
  18. from rpy2.robjects.packages import importr
  19. knitr = importr('knitr')
  20. idx = knitr.opts_knit.names.index('set')
  21. PATH = pelicanobj.settings.get('PATH','%s/content' % settings.DEFAULT_CONFIG.get('PATH'))
  22. logger.debug("RMD_READER PATH = %s", PATH)
  23. knitr.opts_knit[idx](**{'base.dir': PATH})
  24. idx = knitr.opts_chunk.names.index('set')
  25. knitroptschunk = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_CHUNK', None)
  26. if knitroptschunk is not None:
  27. knitr.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.iteritems()})
  28. rmd = True
  29. except ImportError as ex:
  30. rmd = False
  31. class RmdReader(readers.BaseReader):
  32. file_extensions = ['Rmd', 'rmd']
  33. @property
  34. def enabled():
  35. global rmd
  36. return rmd
  37. # You need to have a read method, which takes a filename and returns
  38. # some content and the associated metadata.
  39. def read(self, filename):
  40. """Parse content and metadata of markdown files"""
  41. global knitr
  42. QUIET = self.settings.get('RMD_READER_KNITR_QUIET', True)
  43. ENCODING = self.settings.get('RMD_READER_KNITR_ENCODING', 'UTF-8')
  44. CLEANUP = self.settings.get('RMD_READER_CLEANUP', True)
  45. logger.debug("RMD_READER_KNITR_QUIET = %s", QUIET)
  46. logger.debug("RMD_READER_KNITR_QUIET = %s", ENCODING)
  47. logger.debug("RMD_READER_CLEANUP = %s", CLEANUP)
  48. # replace single backslashes with double backslashes
  49. filename = filename.replace('\\', '\\\\')
  50. # parse Rmd file - generate md file
  51. md_filename = filename.replace('.Rmd', '.aux').replace('.rmd', '.aux')
  52. knitr.knit(filename, md_filename, quiet=QUIET, encoding=ENCODING)
  53. # read md file - create a MarkdownReader
  54. md_reader = readers.MarkdownReader(self.settings)
  55. content, metadata = md_reader.read(md_filename)
  56. # remove md file
  57. if CLEANUP:
  58. os.remove(md_filename)
  59. return content, metadata
  60. def add_reader(readers):
  61. readers.reader_classes['rmd'] = RmdReader
  62. def register():
  63. signals.readers_init.connect(add_reader)
  64. signals.initialized.connect(initsignal)