1#
2# ploteditor.py
3#
4# This is a plugin for Zim, which allows inserting GNU R scripts to
5# have Zim generate plots from them.
6#
7# Author: Lee Braiden <lee.b@irukado.org>
8# Date: 2010-03-13
9# Copyright (c) 2010, released under the GNU GPL v2 or higher
10#
11# Heavily based on equationeditor.py plugin as of:
12# bzr revno 212, (2010-03-10), marked as
13# Copyright 2009 Jaap Karssenberg <jaap.karssenberg@gmail.com>
14#
15
16import glob
17import re
18
19from zim.plugins import PluginClass
20from zim.plugins.base.imagegenerator import \
21	ImageGeneratorClass, BackwardImageGeneratorObjectType
22
23from zim.fs import File, TmpFile
24from zim.config import data_file
25from zim.templates import get_template
26from zim.applications import Application
27
28# TODO put these commands in preferences
29gnu_r_cmd = ('R',)
30
31
32class InsertGNURPlotPlugin(PluginClass):
33
34	plugin_info = {
35		'name': _('Insert GNU R Plot'), # T: plugin name
36		'description': _('''\
37This plugin provides a plot editor for zim based on GNU R.
38'''), # T: plugin description
39		'help': 'Plugins:GNU R Plot Editor',
40		'author': 'Lee Braiden',
41	}
42
43	@classmethod
44	def check_dependencies(klass):
45		has_gnur = Application(gnu_r_cmd).tryexec()
46		return has_gnur, [('GNU R', has_gnur, True)]
47
48
49class BackwardGnuRPlotImageObjectType(BackwardImageGeneratorObjectType):
50
51	name = 'image+gnu_r_plot'
52	label = _('GNU R Plot') # T: menu item
53	syntax = 'r'
54	scriptname = 'gnu_r_plot.r'
55	imagefile_extension = '.png'
56
57
58class GNURPlotGenerator(ImageGeneratorClass):
59
60	def __init__(self, plugin, notebook, page):
61		ImageGeneratorClass.__init__(self, plugin, notebook, page)
62		self.template = get_template('plugins', 'gnu_r_editor.r')
63		self.plotscriptfile = TmpFile('gnu_r_plot.r')
64
65	def generate_image(self, text):
66		plotscriptfile = self.plotscriptfile
67		pngfile = File(plotscriptfile.path[:-2] + '.png')
68
69		plot_width = 480 # default image width (px)
70		plot_height = 480 # default image height (px)
71
72		# LOOK for image size in comments of the script
73		r = re.search(r"^#\s*WIDTH\s*=\s*([0-9]+)$", text, re.M)
74		if r:
75			plot_width = int(r.group(1))
76		r = re.search(r"^#\s*HEIGHT\s*=\s*([0-9]+)$", text, re.M)
77		if r:
78			plot_height = int(r.group(1))
79
80		template_vars = {
81			'gnu_r_plot_script': text,
82			'r_width': plot_width,
83			'r_height': plot_height,
84			'png_fname': pngfile.path.replace('\\', '/'),
85				# Even on windows, GNU R expects unix path seperator
86		}
87
88		# Write to tmp file usign the template for the header / footer
89		lines = []
90		self.template.process(lines, template_vars)
91		plotscriptfile.writelines(lines)
92		#print '>>>%s<<<' % plotscriptfile.read()
93
94		# Call GNU R
95		try:
96			gnu_r = Application(gnu_r_cmd)
97			#~ gnu_r.run(args=('-f', plotscriptfile.basename, ), cwd=plotscriptfile.dir)
98			gnu_r.run(args=('-f', plotscriptfile.basename, '--vanilla'), cwd=plotscriptfile.dir)
99		except:
100			return None, None # Sorry, no log
101		else:
102			return pngfile, None
103
104	def cleanup(self):
105		path = self.plotscriptfile.path
106		for path in glob.glob(path[:-2] + '.*'):
107			File(path).remove()
108