1 # -*- coding: iso-8859-1 -*-
2 """
3 MoinMoin - SvgPlot Macro
4
5 This macro is a mockup for svg graphics by svgfig, http://code.google.com/p/svgfig/
6
7 @copyright: 2008 MoinMoin:ReimarBauer
8 @license: GNU GPL, see COPYING for details.
9 """
10 import re, svgfig, time
11 from MoinMoin import wikiutil
12 from MoinMoin.Page import Page
13 from MoinMoin.action import cache
14 from MoinMoin.macro import EmbedObject
15
16 svgfig._canvas_defaults["width"] = '400px'
17 svgfig._canvas_defaults["height"] = '400px'
18
19
20 class DictBase(dict):
21 """ Base class for wiki dicts
22
23 To use this class, subclass it and override regex and initFromText.
24 """
25 def __init__(self, request=None, pagename=None, rev=0):
26 dict.__init__(self)
27 self.name = None
28 if request is not None and pagename is not None:
29 self.loadFromPage(request, pagename, rev=rev)
30
31 # Regular expression used to parse text - subclass must override this
32 regex = None # re.compile(u'...', re.MULTILINE | re.UNICODE)
33
34 def loadFromPage(self, request, name, rev=0):
35 """ load the dict from wiki page <name>'s content """
36 self.name = name
37 text = Page(request, name, rev=rev).get_raw_body()
38 self.initFromText(text)
39
40 def initFromText(self, text):
41 """ parse the wiki page text and init the dict from it """
42 raise NotImplementedError('subclasses should override this')
43
44
45 class Dict(DictBase):
46 """ Mapping of keys to values in a wiki page.
47
48 How a Dict definition page should look like:
49
50 any text ignored
51 key1:: value1
52 * ignored, too
53 key2:: value2 containing spaces
54 ...
55 keyn:: ....
56 any text ignored
57 """
58 # Key:: Value - ignore all but key:: value pairs, strip whitespace, exactly one space after the :: is required
59 regex = re.compile(ur'^ (?P<key>.+?):: (?P<val>.*?) *$', re.MULTILINE | re.UNICODE)
60
61 def initFromText(self, text):
62 for match in self.regex.finditer(text):
63 key, val = match.groups()
64 self[key] = val
65
66 def __repr__(self):
67 return "<Dict name=%r items=%r>" % (self.name, self.items())
68
69 def macro_SvgPlot(macro,
70 width=u'400px',
71 height=u'400px',
72 parameter=u'cpu MHz'
73 ):
74
75
76 request = macro.request
77 pagename = request.page.page_name
78 cache_arena = 'sendcache'
79 cache_scope = 'wiki'
80 content_type = 'image/svg+xml'
81 do_locking = False
82 current_rev = Page(request, pagename).current_rev()
83
84 # example data
85 y = []
86 for rev in range(current_rev):
87 try:
88 page_dict = Dict(request, pagename, rev=rev)
89 y.append(float(page_dict[parameter].split()[0]))
90 except:
91 y.append(0)
92
93 x = range(current_rev)
94 if current_rev < 10:
95 xrange = (0, 10)
96 else:
97 xrange = (0, max(x))
98
99 points1 = svgfig.Dots(zip(x, y), svgfig.make_symbol("data1", stroke="black", fill="red", stroke_width="0.25pt"))
100 #points2 = svgfig.Dots(zip(x, y2), svgfig.make_symbol("data2", stroke="black", fill="blue", stroke_width="0.25pt"))
101 # define scientific plot
102 svgfig.Frame.text_ytitle_offset = 16
103 myFrame = svgfig.Frame(xrange[0], xrange[1], 0, max(y) + 0.05 * max(y), points1, xtitle='~days (%s)' % (pagename.split('/')[1]), ytitle=parameter).SVG()
104 # create complete svg xml
105 data = myFrame.standalone_xml()
106 # create key
107 key = cache.key(request, itemname=pagename, content=data)
108 size_str = "%s_%s" % (svgfig._canvas_defaults["width"].replace('px', ''), svgfig._canvas_defaults["height"].replace('px', ''))
109 key = '%s_%s_%s' % (wikiutil.escape(content_type.replace('/', '_')), size_str, key)
110 # check caching status
111 if not cache.exists(request, key):
112 cache.put(request, key, data, content_type=content_type)
113 # create url to cache file
114 url = "%s%s%s" % (request.getQualifiedURL(), Page(request, pagename).url(request), cache.url(request, key))
115 from MoinMoin import macro
116 from MoinMoin.parser.text import Parser
117 macro.request = request
118 macro.formatter = request.html_formatter
119 p = Parser("##\n", request)
120 m = macro.Macro(p)
121 return m.execute('EmbedObject', u'width=%s, height=%s, target=%s, url_mimetype=%s' % (width, height, url, content_type))
Current configuration does not allow embedding of the file example.svg because of its mimetype image/svg+xml.: example.svg
Discussion
I install this macro. System moinmoin 1.8.4, FreeBSD 6.3, Python 2.6, py26-SVGFig-1.1.6. Not drawing SVG on wiki, error "list index out of range". Consol make SVG on phyton, working.
Try it with a page Example/TestPage?action=raw
cpu MHz:: 4 <<SvgPlot>>
and create different revisions of this page by changing the value. This macro is currently only a mockup to show how one could interact with svgfig. Also it show how to use data from old revisions. And how to call a macro from another macro (or some other code). And how to use the action cache. Probably later I will add it to MoinAPI/Beispiele