Show More
@@ -1,19 +1,12 b'' | |||
|
1 | """ Leo plugin for IPython | |
|
1 | """ ILeo - Leo plugin for IPython | |
|
2 | 2 | |
|
3 | Example use: | |
|
4 | ||
|
5 | nodes.foo = "hello world" | |
|
6 | ||
|
7 | -> create '@ipy foo' node with text "hello world" | |
|
8 | ||
|
9 | Access works also, and so does tab completion. | |
|
10 | 3 | |
|
11 | 4 | """ |
|
12 | 5 | import IPython.ipapi |
|
13 | 6 | import IPython.genutils |
|
14 | 7 | import IPython.generics |
|
15 | 8 | import re |
|
16 | ||
|
9 | import UserDict | |
|
17 | 10 | |
|
18 | 11 | |
|
19 | 12 | ip = IPython.ipapi.get() |
@@ -41,42 +34,20 b' def format_for_leo(obj):' | |||
|
41 | 34 | def format_list(obj): |
|
42 | 35 | return "\n".join(str(s) for s in obj) |
|
43 | 36 | |
|
44 | nodename_re = r'^(@ipy\w*\s+)?(\w+)$' | |
|
37 | attribute_re = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') | |
|
38 | def valid_attribute(s): | |
|
39 | return attribute_re.match(s) | |
|
45 | 40 | |
|
46 | 41 | def all_cells(): |
|
47 | 42 | d = {} |
|
48 | 43 | for p in c.allNodes_iter(): |
|
49 | 44 | h = p.headString() |
|
50 | if h.startswith('@') and len(h.split()) == 1: | |
|
51 | continue | |
|
52 | mo = re.match(nodename_re, h) | |
|
53 | if not mo: | |
|
54 | continue | |
|
55 | d[mo.group(2)] = p.copy() | |
|
45 | if not valid_attribute(h): | |
|
46 | continue | |
|
47 | d[h] = p.copy() | |
|
56 | 48 | return d |
|
57 | 49 | |
|
58 | 50 | |
|
59 | class TrivialLeoWorkbook: | |
|
60 | """ class to find cells with simple syntax | |
|
61 | ||
|
62 | """ | |
|
63 | def __getattr__(self, key): | |
|
64 | cells = all_cells() | |
|
65 | p = cells[key] | |
|
66 | body = p.bodyString() | |
|
67 | return eval_body(body) | |
|
68 | def __setattr__(self,key,val): | |
|
69 | cells = all_cells() | |
|
70 | p = cells.get(key,None) | |
|
71 | if p is None: | |
|
72 | add_var(key,val) | |
|
73 | else: | |
|
74 | c.setBodyString(p,format_for_leo(val)) | |
|
75 | def __str__(self): | |
|
76 | return "<TrivialLeoWorkbook>" | |
|
77 | __repr__ = __str__ | |
|
78 | ||
|
79 | ip.user_ns['nodes'] = TrivialLeoWorkbook() | |
|
80 | 51 | |
|
81 | 52 | def eval_node(n): |
|
82 | 53 | body = n.b |
@@ -85,14 +56,21 b' def eval_node(n):' | |||
|
85 | 56 | return ip.ev(n.b) |
|
86 | 57 | # @cl nodes deserve special treatment - first eval the first line (minus cl), then use it to call the rest of body |
|
87 | 58 | first, rest = body.split('\n',1) |
|
88 |
|
|
|
89 | if cl != '@cl': | |
|
90 | return None | |
|
59 | tup = first.split(None, 1) | |
|
60 | # @cl alone SPECIAL USE-> dump var to user_ns | |
|
61 | if len(tup) == 1: | |
|
62 | val = ip.ev(rest) | |
|
63 | ip.user_ns[n.h] = val | |
|
64 | es("%s = %s" % (n.h, repr(val)[:20] )) | |
|
65 | return val | |
|
66 | ||
|
67 | cl, hd = tup | |
|
68 | ||
|
91 | 69 | xformer = ip.ev(hd.strip()) |
|
92 | 70 | es('Transform w/ %s' % repr(xformer)) |
|
93 | 71 | return xformer(rest) |
|
94 | 72 | |
|
95 | class LeoNode(object): | |
|
73 | class LeoNode(object, UserDict.DictMixin): | |
|
96 | 74 | def __init__(self,p): |
|
97 | 75 | self.p = p.copy() |
|
98 | 76 | |
@@ -130,12 +108,48 b' class LeoNode(object):' | |||
|
130 | 108 | |
|
131 | 109 | def __iter__(self): |
|
132 | 110 | return (LeoNode(p) for p in self.p.children_iter()) |
|
133 | ||
|
111 | ||
|
112 | def _children(self): | |
|
113 | d = {} | |
|
114 | for child in self: | |
|
115 | head = child.h | |
|
116 | tup = head.split(None,1) | |
|
117 | if len(tup) > 1 and tup[0] == '@k': | |
|
118 | d[tup[1]] = child | |
|
119 | continue | |
|
120 | ||
|
121 | if not valid_attribute(head): | |
|
122 | d[head] = child | |
|
123 | continue | |
|
124 | return d | |
|
125 | def keys(self): | |
|
126 | d = self._children() | |
|
127 | return d.keys() | |
|
128 | def __getitem__(self, key): | |
|
129 | key = str(key) | |
|
130 | d = self._children() | |
|
131 | return d[key] | |
|
132 | def __setitem__(self, key, val): | |
|
133 | key = str(key) | |
|
134 | d = self._children() | |
|
135 | if key in d: | |
|
136 | d[key].v = val | |
|
137 | return | |
|
138 | ||
|
139 | if not valid_attribute(key): | |
|
140 | head = key | |
|
141 | else: | |
|
142 | head = '@k ' + key | |
|
143 | p = c.createLastChildNode(self.p, head, '') | |
|
144 | LeoNode(p).v = val | |
|
145 | def __delitem__(self,key): | |
|
146 | pass | |
|
147 | ||
|
134 | 148 | |
|
135 | 149 | class LeoWorkbook: |
|
136 | 150 | """ class for 'advanced' node access """ |
|
137 | 151 | def __getattr__(self, key): |
|
138 | if key.startswith('_') or key == 'trait_names': | |
|
152 | if key.startswith('_') or key == 'trait_names' or not valid_attribute(key): | |
|
139 | 153 | raise AttributeError |
|
140 | 154 | cells = all_cells() |
|
141 | 155 | p = cells.get(key, None) |
@@ -146,6 +160,9 b' class LeoWorkbook:' | |||
|
146 | 160 | |
|
147 | 161 | def __str__(self): |
|
148 | 162 | return "<LeoWorkbook>" |
|
163 | def __setattr__(self,key, val): | |
|
164 | raise AttributeError("Direct assignment to workbook denied, try wb.%s.v = %s" % (key,val)) | |
|
165 | ||
|
149 | 166 | __repr__ = __str__ |
|
150 | 167 | ip.user_ns['wb'] = LeoWorkbook() |
|
151 | 168 |
@@ -3,30 +3,27 b'' | |||
|
3 | 3 | <leo_file> |
|
4 | 4 | <leo_header file_format="2" tnodes="0" max_tnode_index="0" clone_windows="0"/> |
|
5 | 5 | <globals body_outline_ratio="0.5"> |
|
6 |
<global_window_position top=" |
|
|
6 | <global_window_position top="262" left="259" height="600" width="800"/> | |
|
7 | 7 | <global_log_window_position top="0" left="0" height="0" width="0"/> |
|
8 | 8 | </globals> |
|
9 | 9 | <preferences/> |
|
10 | 10 | <find_panel_settings/> |
|
11 | 11 | <vnodes> |
|
12 | 12 | <v t="vivainio.20080218184525"><vh>@chapters</vh></v> |
|
13 | <v t="vivainio.20080218184540" a="E"><vh>@ipy-startup</vh> | |
|
14 |
<v t="vivainio.20080218184613"><vh> |
|
|
15 |
<v t="vivainio.20080218 |
|
|
16 | <v t="vivainio.20080218200031" a="E"><vh>Some classes</vh> | |
|
13 | <v t="vivainio.20080218184540" a="ET"><vh>@ipy-startup</vh> | |
|
14 | <v t="vivainio.20080218184613.1" a="V"><vh>b</vh></v> | |
|
15 | <v t="vivainio.20080218200031"><vh>Some classes</vh> | |
|
17 | 16 | <v t="vivainio.20080218190816"><vh>File-like access</vh></v> |
|
18 | 17 | <v t="vivainio.20080218200106"><vh>csv data</vh></v> |
|
19 | 18 | </v> |
|
20 | 19 | </v> |
|
21 | <v t="vivainio.20080218195413"><vh>Class tests</vh> | |
|
20 | <v t="vivainio.20080218195413" a="E"><vh>Class tests</vh> | |
|
22 | 21 | <v t="vivainio.20080218200509"><vh>csvr</vh></v> |
|
23 | 22 | <v t="vivainio.20080218191007"><vh>tempfile</vh></v> |
|
24 | 23 | <v t="vivainio.20080218195413.1"><vh>rfile</vh></v> |
|
25 | 24 | </v> |
|
26 | 25 | <v t="vivainio.20080218201219" a="E"><vh>Direct variables</vh> |
|
27 |
<v t="vivainio.20080218201219. |
|
|
28 | <v t="vivainio.20080218201622"><vh>@ipy </vh></v> | |
|
29 | <v t="vivainio.20080218201219.2"><vh>@ipy bar</vh></v> | |
|
26 | <v t="vivainio.20080218201219.2"><vh>bar</vh></v> | |
|
30 | 27 | </v> |
|
31 | 28 | </vnodes> |
|
32 | 29 | <tnodes> |
@@ -34,7 +31,6 b'' | |||
|
34 | 31 | <t tx="vivainio.20080218184540"># this stuff will be pushed at ipython bridge startup |
|
35 | 32 | |
|
36 | 33 | @others</t> |
|
37 | <t tx="vivainio.20080218184613">print "hello"</t> | |
|
38 | 34 | <t tx="vivainio.20080218184613.1">print "world"</t> |
|
39 | 35 | <t tx="vivainio.20080218190816">def rfile(body): |
|
40 | 36 | """ @cl rfile |
@@ -60,7 +56,7 b' def tmpfile(body):' | |||
|
60 | 56 | <t tx="vivainio.20080218191007">@cl tmpfile |
|
61 | 57 | |
|
62 | 58 | Hello</t> |
|
63 | <t tx="vivainio.20080218195413"></t> | |
|
59 | <t tx="vivainio.20080218195413">?</t> | |
|
64 | 60 | <t tx="vivainio.20080218195413.1">@cl rfile |
|
65 | 61 | These |
|
66 | 62 | lines |
@@ -78,9 +74,6 b' readable </t>' | |||
|
78 | 74 | a,b,b |
|
79 | 75 | 1,2,2</t> |
|
80 | 76 | <t tx="vivainio.20080218201219"></t> |
|
81 | <t tx="vivainio.20080218201219.1">@cl rfile | |
|
82 | 121212</t> | |
|
83 | 77 | <t tx="vivainio.20080218201219.2">"hello world"</t> |
|
84 | <t tx="vivainio.20080218201622"></t> | |
|
85 | 78 | </tnodes> |
|
86 | 79 | </leo_file> |
General Comments 0
You need to be logged in to leave comments.
Login now