Show More
@@ -1,7 +1,7 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | """Magic functions for InteractiveShell. |
|
2 | """Magic functions for InteractiveShell. | |
3 |
|
3 | |||
4 |
$Id: Magic.py 2 |
|
4 | $Id: Magic.py 2104 2007-02-20 10:25:51Z fperez $""" | |
5 |
|
5 | |||
6 | #***************************************************************************** |
|
6 | #***************************************************************************** | |
7 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and |
|
7 | # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and | |
@@ -454,15 +454,28 b' Currently the magic system has the following functions:\\n"""' | |||||
454 | def magic_automagic(self, parameter_s = ''): |
|
454 | def magic_automagic(self, parameter_s = ''): | |
455 | """Make magic functions callable without having to type the initial %. |
|
455 | """Make magic functions callable without having to type the initial %. | |
456 |
|
456 | |||
457 |
|
|
457 | Without argumentsl toggles on/off (when off, you must call it as | |
458 | course). Note that magic functions have lowest priority, so if there's |
|
458 | %automagic, of course). With arguments it sets the value, and you can | |
459 | a variable whose name collides with that of a magic fn, automagic |
|
459 | use any of (case insensitive): | |
460 | won't work for that function (you get the variable instead). However, |
|
460 | ||
461 | if you delete the variable (del var), the previously shadowed magic |
|
461 | - on,1,True: to activate | |
462 | function becomes visible to automagic again.""" |
|
462 | ||
|
463 | - off,0,False: to deactivate. | |||
|
464 | ||||
|
465 | Note that magic functions have lowest priority, so if there's a | |||
|
466 | variable whose name collides with that of a magic fn, automagic won't | |||
|
467 | work for that function (you get the variable instead). However, if you | |||
|
468 | delete the variable (del var), the previously shadowed magic function | |||
|
469 | becomes visible to automagic again.""" | |||
463 |
|
470 | |||
464 | rc = self.shell.rc |
|
471 | rc = self.shell.rc | |
465 | rc.automagic = not rc.automagic |
|
472 | arg = parameter_s.lower() | |
|
473 | if parameter_s in ('on','1','true'): | |||
|
474 | rc.automagic = True | |||
|
475 | elif parameter_s in ('off','0','false'): | |||
|
476 | rc.automagic = False | |||
|
477 | else: | |||
|
478 | rc.automagic = not rc.automagic | |||
466 | print '\n' + Magic.auto_status[rc.automagic] |
|
479 | print '\n' + Magic.auto_status[rc.automagic] | |
467 |
|
480 | |||
468 | def magic_autocall(self, parameter_s = ''): |
|
481 | def magic_autocall(self, parameter_s = ''): |
@@ -23,6 +23,13 b' The classes are (see their docstrings for further details):' | |||||
23 | - IPythonLineDemo: IPython version of the LineDemo class (the demo is |
|
23 | - IPythonLineDemo: IPython version of the LineDemo class (the demo is | |
24 | executed a line at a time, but processed via IPython). |
|
24 | executed a line at a time, but processed via IPython). | |
25 |
|
25 | |||
|
26 | - ClearMixin: mixin to make Demo classes with less visual clutter. It | |||
|
27 | declares an empty marquee and a pre_cmd that clears the screen before each | |||
|
28 | block (see Subclassing below). | |||
|
29 | ||||
|
30 | - ClearDemo, ClearIPDemo: mixin-enabled versions of the Demo and IPythonDemo | |||
|
31 | classes. | |||
|
32 | ||||
26 |
|
33 | |||
27 | Subclassing |
|
34 | Subclassing | |
28 | =========== |
|
35 | =========== | |
@@ -35,7 +42,7 b' subclassing more convenient. Their docstrings below have some more details:' | |||||
35 |
|
42 | |||
36 | - pre_cmd(): run right before the execution of each block. |
|
43 | - pre_cmd(): run right before the execution of each block. | |
37 |
|
44 | |||
38 |
- p |
|
45 | - post_cmd(): run right after the execution of each block. If the block | |
39 | raises an exception, this is NOT called. |
|
46 | raises an exception, this is NOT called. | |
40 |
|
47 | |||
41 |
|
48 | |||
@@ -56,11 +63,17 b' behavior.' | |||||
56 |
|
63 | |||
57 | The supported tags are: |
|
64 | The supported tags are: | |
58 |
|
65 | |||
59 |
# <demo> |
|
66 | # <demo> stop | |
60 |
|
67 | |||
61 | Defines block boundaries, the points where IPython stops execution of the |
|
68 | Defines block boundaries, the points where IPython stops execution of the | |
62 | file and returns to the interactive prompt. |
|
69 | file and returns to the interactive prompt. | |
63 |
|
70 | |||
|
71 | You can optionally mark the stop tag with extra dashes before and after the | |||
|
72 | word 'stop', to help visually distinguish the blocks in a text editor: | |||
|
73 | ||||
|
74 | # <demo> --- stop --- | |||
|
75 | ||||
|
76 | ||||
64 | # <demo> silent |
|
77 | # <demo> silent | |
65 |
|
78 | |||
66 | Make a block execute silently (and hence automatically). Typically used in |
|
79 | Make a block execute silently (and hence automatically). Typically used in | |
@@ -110,21 +123,22 b' The following is a very simple example of a valid demo file.' | |||||
110 | print 'Hello, welcome to an interactive IPython demo.' |
|
123 | print 'Hello, welcome to an interactive IPython demo.' | |
111 |
|
124 | |||
112 | # The mark below defines a block boundary, which is a point where IPython will |
|
125 | # The mark below defines a block boundary, which is a point where IPython will | |
113 | # stop execution and return to the interactive prompt. |
|
126 | # stop execution and return to the interactive prompt. The dashes are actually | |
114 | # Note that in actual interactive execution, |
|
127 | # optional and used only as a visual aid to clearly separate blocks while | |
115 | # <demo> --- stop --- |
|
128 | editing the demo code. | |
|
129 | # <demo> stop | |||
116 |
|
130 | |||
117 | x = 1 |
|
131 | x = 1 | |
118 | y = 2 |
|
132 | y = 2 | |
119 |
|
133 | |||
120 |
# <demo> |
|
134 | # <demo> stop | |
121 |
|
135 | |||
122 | # the mark below makes this block as silent |
|
136 | # the mark below makes this block as silent | |
123 | # <demo> silent |
|
137 | # <demo> silent | |
124 |
|
138 | |||
125 | print 'This is a silent block, which gets executed but not printed.' |
|
139 | print 'This is a silent block, which gets executed but not printed.' | |
126 |
|
140 | |||
127 |
# <demo> |
|
141 | # <demo> stop | |
128 | # <demo> auto |
|
142 | # <demo> auto | |
129 | print 'This is an automatic block.' |
|
143 | print 'This is an automatic block.' | |
130 | print 'It is executed without asking for confirmation, but printed.' |
|
144 | print 'It is executed without asking for confirmation, but printed.' | |
@@ -132,7 +146,7 b' z = x+y' | |||||
132 |
|
146 | |||
133 | print 'z=',x |
|
147 | print 'z=',x | |
134 |
|
148 | |||
135 |
# <demo> |
|
149 | # <demo> stop | |
136 | # This is just another normal block. |
|
150 | # This is just another normal block. | |
137 | print 'z is now:', z |
|
151 | print 'z is now:', z | |
138 |
|
152 | |||
@@ -164,9 +178,9 b' class DemoError(exceptions.Exception): pass' | |||||
164 | def re_mark(mark): |
|
178 | def re_mark(mark): | |
165 | return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE) |
|
179 | return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE) | |
166 |
|
180 | |||
167 | class Demo: |
|
181 | class Demo(object): | |
168 |
|
182 | |||
169 |
re_stop = re_mark('- |
|
183 | re_stop = re_mark('-?\s?stop\s?-?') | |
170 | re_silent = re_mark('silent') |
|
184 | re_silent = re_mark('silent') | |
171 | re_auto = re_mark('auto') |
|
185 | re_auto = re_mark('auto') | |
172 | re_auto_all = re_mark('auto_all') |
|
186 | re_auto_all = re_mark('auto_all') | |
@@ -271,7 +285,12 b' class Demo:' | |||||
271 | return index |
|
285 | return index | |
272 |
|
286 | |||
273 | def seek(self,index): |
|
287 | def seek(self,index): | |
274 |
"""Move the current seek pointer to the given block |
|
288 | """Move the current seek pointer to the given block. | |
|
289 | ||||
|
290 | You can use negative indices to seek from the end, with identical | |||
|
291 | semantics to those of Python lists.""" | |||
|
292 | if index<0: | |||
|
293 | index = self.nblocks + index | |||
275 | self._validate_index(index) |
|
294 | self._validate_index(index) | |
276 | self.block_index = index |
|
295 | self.block_index = index | |
277 | self.finished = False |
|
296 | self.finished = False | |
@@ -280,8 +299,10 b' class Demo:' | |||||
280 | """Move the seek pointer back num blocks (default is 1).""" |
|
299 | """Move the seek pointer back num blocks (default is 1).""" | |
281 | self.seek(self.block_index-num) |
|
300 | self.seek(self.block_index-num) | |
282 |
|
301 | |||
283 | def jump(self,num): |
|
302 | def jump(self,num=1): | |
284 |
"""Jump a given number of blocks relative to the current one. |
|
303 | """Jump a given number of blocks relative to the current one. | |
|
304 | ||||
|
305 | The offset can be positive or negative, defaults to 1.""" | |||
285 | self.seek(self.block_index+num) |
|
306 | self.seek(self.block_index+num) | |
286 |
|
307 | |||
287 | def again(self): |
|
308 | def again(self): | |
@@ -327,7 +348,7 b' class Demo:' | |||||
327 |
|
348 | |||
328 | print self.marquee('<%s> block # %s (%s remaining)' % |
|
349 | print self.marquee('<%s> block # %s (%s remaining)' % | |
329 | (self.fname,index,self.nblocks-index-1)) |
|
350 | (self.fname,index,self.nblocks-index-1)) | |
330 |
|
|
351 | sys.stdout.write(self.src_blocks_colored[index]) | |
331 | sys.stdout.flush() |
|
352 | sys.stdout.flush() | |
332 |
|
353 | |||
333 | def show_all(self): |
|
354 | def show_all(self): | |
@@ -375,7 +396,7 b' class Demo:' | |||||
375 | self.pre_cmd() |
|
396 | self.pre_cmd() | |
376 | self.show(index) |
|
397 | self.show(index) | |
377 | if self.auto_all or self._auto[index]: |
|
398 | if self.auto_all or self._auto[index]: | |
378 | print marquee('output') |
|
399 | print marquee('output:') | |
379 | else: |
|
400 | else: | |
380 | print marquee('Press <q> to quit, <Enter> to execute...'), |
|
401 | print marquee('Press <q> to quit, <Enter> to execute...'), | |
381 | ans = raw_input().strip() |
|
402 | ans = raw_input().strip() | |
@@ -396,9 +417,12 b' class Demo:' | |||||
396 | self.ip_ns.update(self.user_ns) |
|
417 | self.ip_ns.update(self.user_ns) | |
397 |
|
418 | |||
398 | if self.block_index == self.nblocks: |
|
419 | if self.block_index == self.nblocks: | |
399 |
|
420 | mq1 = self.marquee('END OF DEMO') | ||
400 | print self.marquee(' END OF DEMO ') |
|
421 | if mq1: | |
401 | print self.marquee('Use reset() if you want to rerun it.') |
|
422 | # avoid spurious prints if empty marquees are used | |
|
423 | ||||
|
424 | print mq1 | |||
|
425 | print self.marquee('Use reset() if you want to rerun it.') | |||
402 | self.finished = True |
|
426 | self.finished = True | |
403 |
|
427 | |||
404 | # These methods are meant to be overridden by subclasses who may wish to |
|
428 | # These methods are meant to be overridden by subclasses who may wish to | |
@@ -462,6 +486,41 b' class LineDemo(Demo):' | |||||
462 | # ensure clean namespace and seek offset |
|
486 | # ensure clean namespace and seek offset | |
463 | self.reset() |
|
487 | self.reset() | |
464 |
|
488 | |||
|
489 | ||||
465 | class IPythonLineDemo(IPythonDemo,LineDemo): |
|
490 | class IPythonLineDemo(IPythonDemo,LineDemo): | |
466 | """Variant of the LineDemo class whose input is processed by IPython.""" |
|
491 | """Variant of the LineDemo class whose input is processed by IPython.""" | |
467 | pass |
|
492 | pass | |
|
493 | ||||
|
494 | ||||
|
495 | class ClearMixin(object): | |||
|
496 | """Use this mixin to make Demo classes with less visual clutter. | |||
|
497 | ||||
|
498 | Demos using this mixin will clear the screen before every block and use | |||
|
499 | blank marquees. | |||
|
500 | ||||
|
501 | Note that in order for the methods defined here to actually override those | |||
|
502 | of the classes it's mixed with, it must go /first/ in the inheritance | |||
|
503 | tree. For example: | |||
|
504 | ||||
|
505 | class ClearIPDemo(ClearMixin,IPythonDemo): pass | |||
|
506 | ||||
|
507 | will provide an IPythonDemo class with the mixin's features. | |||
|
508 | """ | |||
|
509 | ||||
|
510 | def marquee(self,txt='',width=78,mark='*'): | |||
|
511 | """Blank marquee that returns '' no matter what the input.""" | |||
|
512 | return '' | |||
|
513 | ||||
|
514 | def pre_cmd(self): | |||
|
515 | """Method called before executing each block. | |||
|
516 | ||||
|
517 | This one simply clears the screen.""" | |||
|
518 | os.system('clear') | |||
|
519 | ||||
|
520 | ||||
|
521 | class ClearDemo(ClearMixin,Demo): | |||
|
522 | pass | |||
|
523 | ||||
|
524 | ||||
|
525 | class ClearIPDemo(ClearMixin,IPythonDemo): | |||
|
526 | pass |
@@ -1,3 +1,11 b'' | |||||
|
1 | 2007-02-19 Fernando Perez <Fernando.Perez@colorado.edu> | |||
|
2 | ||||
|
3 | * IPython/demo.py (Demo.re_stop): make dashes optional in demo | |||
|
4 | stop marks. | |||
|
5 | (ClearingMixin): a simple mixin to easily make a Demo class clear | |||
|
6 | the screen in between blocks and have empty marquees. The | |||
|
7 | ClearDemo and ClearIPDemo classes that use it are included. | |||
|
8 | ||||
1 | 2007-02-18 Fernando Perez <Fernando.Perez@colorado.edu> |
|
9 | 2007-02-18 Fernando Perez <Fernando.Perez@colorado.edu> | |
2 |
|
10 | |||
3 | * IPython/irunner.py (pexpect_monkeypatch): patch pexpect to |
|
11 | * IPython/irunner.py (pexpect_monkeypatch): patch pexpect to |
General Comments 0
You need to be logged in to leave comments.
Login now