rmd_reader.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #-*- conding: utf-8 -*-
  2. import os
  3. import warnings
  4. import logging
  5. logger = logging.getLogger('RMD_READER')
  6. from pelican import readers
  7. from pelican import signals
  8. from pelican import settings
  9. knitr = None
  10. rmd = False
  11. def initsignal(pelicanobj):
  12. global knitr, rmd, robjects
  13. try:
  14. with warnings.catch_warnings():
  15. warnings.simplefilter("ignore")
  16. from rpy2.robjects.packages import importr
  17. import rpy2.robjects as robjects
  18. knitr = importr('knitr')
  19. idx = knitr.opts_knit.names.index('set')
  20. PATH = pelicanobj.settings.get('PATH','%s/content' % settings.DEFAULT_CONFIG.get('PATH'))
  21. logger.debug("RMD_READER PATH = %s", PATH)
  22. knitr.opts_knit[idx](**{'base.dir': PATH})
  23. knitroptsknit = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_KNIT', None)
  24. if knitroptsknit:
  25. knitr.opts_knit[idx](**{str(k): v for k,v in knitroptsknit.items()})
  26. idx = knitr.opts_chunk.names.index('set')
  27. knitroptschunk = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_CHUNK', None)
  28. if knitroptschunk:
  29. knitr.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.items()})
  30. rmd = True
  31. except ImportError as ex:
  32. rmd = False
  33. class RmdReader(readers.BaseReader):
  34. file_extensions = ['Rmd', 'rmd']
  35. @property
  36. def enabled():
  37. return rmd
  38. # You need to have a read method, which takes a filename and returns
  39. # some content and the associated metadata.
  40. def read(self, filename):
  41. """Parse content and metadata of markdown files"""
  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. RENAME_PLOT = self.settings.get('RMD_READER_RENAME_PLOT', True)
  46. logger.debug("RMD_READER_KNITR_QUIET = %s", QUIET)
  47. logger.debug("RMD_READER_KNITR_ENCODING = %s", ENCODING)
  48. logger.debug("RMD_READER_CLEANUP = %s", CLEANUP)
  49. logger.debug("RMD_READER_RENAME_PLOT = %s", RENAME_PLOT)
  50. # replace single backslashes with double backslashes
  51. filename = filename.replace('\\', '\\\\')
  52. # parse Rmd file - generate md file
  53. md_filename = filename.replace('.Rmd', '.aux').replace('.rmd', '.aux')
  54. if RENAME_PLOT:
  55. chunk_label = os.path.splitext(os.path.basename(filename))[0]
  56. logger.debug('Chunk label: %s', chunk_label)
  57. robjects.r('''
  58. opts_knit$set(unnamed.chunk.label="{unnamed_chunk_label}")
  59. render_markdown()
  60. hook_plot <- knit_hooks$get('plot')
  61. knit_hooks$set(plot=function(x, options) hook_plot(paste0("{{filename}}/", x), options))
  62. '''.format(unnamed_chunk_label=chunk_label))
  63. knitr.knit(filename, md_filename, quiet=QUIET, encoding=ENCODING)
  64. # read md file - create a MarkdownReader
  65. md_reader = readers.MarkdownReader(self.settings)
  66. content, metadata = md_reader.read(md_filename)
  67. # remove md file
  68. if CLEANUP:
  69. os.remove(md_filename)
  70. return content, metadata
  71. def add_reader(readers):
  72. readers.reader_classes['rmd'] = RmdReader
  73. def register():
  74. signals.readers_init.connect(add_reader)
  75. signals.initialized.connect(initsignal)