Переглянути джерело

Merge pull request #671 from wilsonfreitas/rmd

rmd_reader: New features and py3 compatibility
Justin Mayer 9 роки тому
батько
коміт
c863cb8c43
3 змінених файлів з 84 додано та 30 видалено
  1. 14 16
      rmd_reader/Readme.md
  2. 20 9
      rmd_reader/rmd_reader.py
  3. 50 5
      rmd_reader/test_rmd_reader.py

Різницю між файлами не показано, бо вона завелика
+ 14 - 16
rmd_reader/Readme.md


+ 20 - 9
rmd_reader/rmd_reader.py

@@ -4,32 +4,34 @@ import os
 import warnings
 import logging
 
-logger = logging.getLogger(__name__)
+logger = logging.getLogger('RMD_READER')
 
 from pelican import readers
 from pelican import signals
 from pelican import settings
-from pelican.utils import pelican_open
-from markdown import Markdown
 
 knitr = None
 rmd = False
 
 def initsignal(pelicanobj):
-    global knitr,rmd
+    global knitr, rmd, robjects
     try:
         with warnings.catch_warnings():
             warnings.simplefilter("ignore")
             from rpy2.robjects.packages import importr
+            import rpy2.robjects as robjects
         knitr = importr('knitr')
         idx = knitr.opts_knit.names.index('set')
         PATH = pelicanobj.settings.get('PATH','%s/content' % settings.DEFAULT_CONFIG.get('PATH'))
         logger.debug("RMD_READER PATH = %s", PATH)
         knitr.opts_knit[idx](**{'base.dir': PATH})
+        knitroptsknit = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_KNIT', None)
+        if knitroptsknit:
+            knitr.opts_knit[idx](**{str(k): v for k,v in knitroptsknit.items()})
         idx = knitr.opts_chunk.names.index('set')
         knitroptschunk = pelicanobj.settings.get('RMD_READER_KNITR_OPTS_CHUNK', None)
-        if knitroptschunk is not None:     
-            knitr.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.iteritems()})
+        if knitroptschunk:
+            knitr.opts_chunk[idx](**{str(k): v for k,v in knitroptschunk.items()})
         rmd = True
     except ImportError as ex:
         rmd = False
@@ -39,24 +41,33 @@ class RmdReader(readers.BaseReader):
     
     @property
     def enabled():
-        global rmd
         return rmd
 
     # You need to have a read method, which takes a filename and returns
     # some content and the associated metadata.
     def read(self, filename):
         """Parse content and metadata of markdown files"""
-        global knitr
         QUIET = self.settings.get('RMD_READER_KNITR_QUIET', True)
         ENCODING = self.settings.get('RMD_READER_KNITR_ENCODING', 'UTF-8')
         CLEANUP = self.settings.get('RMD_READER_CLEANUP', True)
+        RENAME_PLOT = self.settings.get('RMD_READER_RENAME_PLOT', True)
         logger.debug("RMD_READER_KNITR_QUIET = %s", QUIET)
-        logger.debug("RMD_READER_KNITR_QUIET = %s", ENCODING)
+        logger.debug("RMD_READER_KNITR_ENCODING = %s", ENCODING)
         logger.debug("RMD_READER_CLEANUP = %s", CLEANUP)
+        logger.debug("RMD_READER_RENAME_PLOT = %s", RENAME_PLOT)
         # replace single backslashes with double backslashes
         filename = filename.replace('\\', '\\\\')
         # parse Rmd file - generate md file
         md_filename = filename.replace('.Rmd', '.aux').replace('.rmd', '.aux')
+        if RENAME_PLOT:
+            chunk_label = os.path.splitext(os.path.basename(filename))[0]
+            logger.debug('Chunk label: %s', chunk_label)
+            robjects.r('''
+opts_knit$set(unnamed.chunk.label="{unnamed_chunk_label}")
+render_markdown()
+hook_plot <- knit_hooks$get('plot')
+knit_hooks$set(plot=function(x, options) hook_plot(paste0("{{filename}}/", x), options))
+            '''.format(unnamed_chunk_label=chunk_label))
         knitr.knit(filename, md_filename, quiet=QUIET, encoding=ENCODING)
         # read md file - create a MarkdownReader
         md_reader = readers.MarkdownReader(self.settings)

+ 50 - 5
rmd_reader/test_rmd_reader.py

@@ -10,7 +10,7 @@ import glob
 from pelican import Pelican
 from pelican.settings import read_settings
 
-logging.basicConfig(stream=sys.stderr, level=logging.CRITICAL)
+logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
 class Test(unittest.TestCase):
 
@@ -19,19 +19,23 @@ class Test(unittest.TestCase):
         try:
             import rpy2
             import rmd_reader
-        except Exception, e:
+        except Exception:
             raise unittest.SkipTest("rpy not installed.  Will not test rmd_reader.")
         
         self.testtitle = 'rtest'
         self.cwd = os.path.dirname(os.path.abspath(__file__))
+        logging.debug(self.cwd)
         
         # Setup content dir and test rmd file
         self.contentdir = os.path.join(self.cwd,'test-content')
+        logging.debug(self.contentdir)
         try:
             os.mkdir(self.contentdir)
         except Exception:
             pass
         self.contentfile = os.path.join(self.contentdir,'test.rmd')
+        logging.debug(self.contentfile)
+        
         self.testrmd = '''Title: %s
 Date: 2014-06-23
 
@@ -46,6 +50,8 @@ plot(cars)
             
         # Setup output dir
         self.outputdir = os.path.join(self.cwd,'test-output')
+        logging.debug(self.outputdir)
+        
         try:
             os.mkdir(self.outputdir)
         except Exception:
@@ -56,17 +62,20 @@ plot(cars)
 
 
     def tearDown(self):
+        logging.debug('CLEAN')
         if os.path.isdir(self.outputdir):
             shutil.rmtree(self.outputdir)
         if os.path.isdir(self.contentdir):
             shutil.rmtree(self.contentdir)
 
-
     def testKnitrSettings(self):
         settings = read_settings(path=None, override={
+            'LOAD_CONTENT_CACHE': False,
             'PATH': self.contentdir,
             'OUTPUT_PATH': self.outputdir,
-            'KNITR_OPTS_CHUNK': {'fig.path' : '%s/' % self.figpath},
+            'RMD_READER_KNITR_OPTS_CHUNK': {'fig.path' : '%s/' % self.figpath},
+            'RMD_READER_KNITR_OPTS_KNIT': {'progress' : True, 'verbose': True},
+            'RMD_READER_RENAME_PLOT': False,
             'PLUGIN_PATHS': ['../'],
             'PLUGINS': ['rmd_reader'],
         })
@@ -75,12 +84,48 @@ plot(cars)
         
         outputfilename = os.path.join(self.outputdir,'%s.html' % self.testtitle)
         self.assertTrue(os.path.exists(outputfilename),'File %s was not created.' % outputfilename)
-        imagesdir = os.path.join(self.outputdir,self.figpath)
+        
+        imagesdir = os.path.join(self.outputdir, self.figpath)
         self.assertTrue(os.path.exists(imagesdir), 'figpath not created.')
+        
+        imagefile = os.path.join(imagesdir, 'unnamed-chunk') + '-1-1.png'
+        logging.debug(imagefile)
         images = glob.glob('%s/*' % imagesdir)
+        logging.debug(images)
+        self.assertTrue(os.path.exists(imagefile), 'image correctly named.')
+        
         self.assertTrue(len(images) == 1,'Contents of images dir is not correct: %s' % ','.join(images))
         
 
+    def testKnitrSettings2(self):
+        settings = read_settings(path=None, override={
+            'LOAD_CONTENT_CACHE': False,
+            'PATH': self.contentdir,
+            'OUTPUT_PATH': self.outputdir,
+            'RMD_READER_KNITR_OPTS_CHUNK': {'fig.path' : '%s/' % self.figpath},
+            'RMD_READER_KNITR_OPTS_KNIT': {'progress' : True, 'verbose': True},
+            'RMD_READER_RENAME_PLOT': True,
+            'PLUGIN_PATHS': ['../'],
+            'PLUGINS': ['rmd_reader'],
+        })
+        pelican = Pelican(settings=settings)
+        pelican.run()
+        
+        outputfilename = os.path.join(self.outputdir,'%s.html' % self.testtitle)
+        self.assertTrue(os.path.exists(outputfilename),'File %s was not created.' % outputfilename)
+        
+        imagesdir = os.path.join(self.outputdir, self.figpath)
+        self.assertTrue(os.path.exists(imagesdir), 'figpath not created.')
+        
+        imagefile = os.path.join(imagesdir, os.path.splitext(os.path.split(self.contentfile)[1])[0]) + '-1-1.png'
+        logging.debug(imagefile)
+        self.assertTrue(os.path.exists(imagefile), 'image correctly named.')
+        
+        images = glob.glob('%s/*' % imagesdir)
+        logging.debug(images)
+        self.assertTrue(len(images) == 1,'Contents of images dir is not correct: %s' % ','.join(images))
+
+
 
 if __name__ == "__main__":
     #import sys;sys.argv = ['', 'Test.testName']