##// END OF EJS Templates
Going back to using uuid.uuid4() for notebook ids....
Brian E. Granger -
Show More
@@ -1,219 +1,218
1 """A notebook manager that uses the local file system for storage.
1 """A notebook manager that uses the local file system for storage.
2
2
3 Authors:
3 Authors:
4
4
5 * Brian Granger
5 * Brian Granger
6 """
6 """
7
7
8 #-----------------------------------------------------------------------------
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2008-2011 The IPython Development Team
9 # Copyright (C) 2008-2011 The IPython Development Team
10 #
10 #
11 # Distributed under the terms of the BSD License. The full license is in
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import datetime
19 import datetime
20 import os
20 import os
21 import uuid
21 import uuid
22 import glob
22 import glob
23
23
24 from tornado import web
24 from tornado import web
25
25
26 from IPython.config.configurable import LoggingConfigurable
26 from IPython.config.configurable import LoggingConfigurable
27 from IPython.nbformat import current
27 from IPython.nbformat import current
28 from IPython.utils.traitlets import Unicode, List, Dict
28 from IPython.utils.traitlets import Unicode, List, Dict
29
29
30
30
31 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 # Code
32 # Code
33 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
34
34
35
35
36 class NotebookManager(LoggingConfigurable):
36 class NotebookManager(LoggingConfigurable):
37
37
38 notebook_dir = Unicode(os.getcwd(), config=True, help="""
38 notebook_dir = Unicode(os.getcwd(), config=True, help="""
39 The directory to use for notebooks.
39 The directory to use for notebooks.
40 """)
40 """)
41 filename_ext = Unicode(u'.ipynb')
41 filename_ext = Unicode(u'.ipynb')
42 allowed_formats = List([u'json',u'py'])
42 allowed_formats = List([u'json',u'py'])
43
43
44 # Map notebook_ids to notebook names
44 # Map notebook_ids to notebook names
45 mapping = Dict()
45 mapping = Dict()
46 # Map notebook names to notebook_ids
46 # Map notebook names to notebook_ids
47 rev_mapping = Dict()
47 rev_mapping = Dict()
48
48
49 def list_notebooks(self):
49 def list_notebooks(self):
50 """List all notebooks in the notebook dir.
50 """List all notebooks in the notebook dir.
51
51
52 This returns a list of dicts of the form::
52 This returns a list of dicts of the form::
53
53
54 dict(notebook_id=notebook,name=name)
54 dict(notebook_id=notebook,name=name)
55 """
55 """
56 names = glob.glob(os.path.join(self.notebook_dir,
56 names = glob.glob(os.path.join(self.notebook_dir,
57 '*' + self.filename_ext))
57 '*' + self.filename_ext))
58 names = [os.path.splitext(os.path.basename(name))[0]
58 names = [os.path.splitext(os.path.basename(name))[0]
59 for name in names]
59 for name in names]
60
60
61 data = []
61 data = []
62 for name in names:
62 for name in names:
63 if name not in self.rev_mapping:
63 if name not in self.rev_mapping:
64 notebook_id = self.new_notebook_id(name)
64 notebook_id = self.new_notebook_id(name)
65 else:
65 else:
66 notebook_id = self.rev_mapping[name]
66 notebook_id = self.rev_mapping[name]
67 data.append(dict(notebook_id=notebook_id,name=name))
67 data.append(dict(notebook_id=notebook_id,name=name))
68 data = sorted(data, key=lambda item: item['name'])
68 data = sorted(data, key=lambda item: item['name'])
69 return data
69 return data
70
70
71 def new_notebook_id(self, name):
71 def new_notebook_id(self, name):
72 """Generate a new notebook_id for a name and store its mappings."""
72 """Generate a new notebook_id for a name and store its mappings."""
73 notebook_id = unicode(uuid.uuid5(uuid.NAMESPACE_URL,
73 notebook_id = unicode(uuid.uuid4())
74 'file://'+self.get_path_by_name(name).encode('utf-8')))
75 self.mapping[notebook_id] = name
74 self.mapping[notebook_id] = name
76 self.rev_mapping[name] = notebook_id
75 self.rev_mapping[name] = notebook_id
77 return notebook_id
76 return notebook_id
78
77
79 def delete_notebook_id(self, notebook_id):
78 def delete_notebook_id(self, notebook_id):
80 """Delete a notebook's id only. This doesn't delete the actual notebook."""
79 """Delete a notebook's id only. This doesn't delete the actual notebook."""
81 name = self.mapping[notebook_id]
80 name = self.mapping[notebook_id]
82 del self.mapping[notebook_id]
81 del self.mapping[notebook_id]
83 del self.rev_mapping[name]
82 del self.rev_mapping[name]
84
83
85 def notebook_exists(self, notebook_id):
84 def notebook_exists(self, notebook_id):
86 """Does a notebook exist?"""
85 """Does a notebook exist?"""
87 if notebook_id not in self.mapping:
86 if notebook_id not in self.mapping:
88 return False
87 return False
89 path = self.get_path_by_name(self.mapping[notebook_id])
88 path = self.get_path_by_name(self.mapping[notebook_id])
90 return os.path.isfile(path)
89 return os.path.isfile(path)
91
90
92 def find_path(self, notebook_id):
91 def find_path(self, notebook_id):
93 """Return a full path to a notebook given its notebook_id."""
92 """Return a full path to a notebook given its notebook_id."""
94 try:
93 try:
95 name = self.mapping[notebook_id]
94 name = self.mapping[notebook_id]
96 except KeyError:
95 except KeyError:
97 raise web.HTTPError(404)
96 raise web.HTTPError(404)
98 return self.get_path_by_name(name)
97 return self.get_path_by_name(name)
99
98
100 def get_path_by_name(self, name):
99 def get_path_by_name(self, name):
101 """Return a full path to a notebook given its name."""
100 """Return a full path to a notebook given its name."""
102 filename = name + self.filename_ext
101 filename = name + self.filename_ext
103 path = os.path.join(self.notebook_dir, filename)
102 path = os.path.join(self.notebook_dir, filename)
104 return path
103 return path
105
104
106 def get_notebook(self, notebook_id, format=u'json'):
105 def get_notebook(self, notebook_id, format=u'json'):
107 """Get the representation of a notebook in format by notebook_id."""
106 """Get the representation of a notebook in format by notebook_id."""
108 format = unicode(format)
107 format = unicode(format)
109 if format not in self.allowed_formats:
108 if format not in self.allowed_formats:
110 raise web.HTTPError(415)
109 raise web.HTTPError(415)
111 last_modified, nb = self.get_notebook_object(notebook_id)
110 last_modified, nb = self.get_notebook_object(notebook_id)
112 data = current.writes(nb, format)
111 data = current.writes(nb, format)
113 name = nb.get('name','notebook')
112 name = nb.get('name','notebook')
114 return last_modified, name, data
113 return last_modified, name, data
115
114
116 def get_notebook_object(self, notebook_id):
115 def get_notebook_object(self, notebook_id):
117 """Get the NotebookNode representation of a notebook by notebook_id."""
116 """Get the NotebookNode representation of a notebook by notebook_id."""
118 path = self.find_path(notebook_id)
117 path = self.find_path(notebook_id)
119 if not os.path.isfile(path):
118 if not os.path.isfile(path):
120 raise web.HTTPError(404)
119 raise web.HTTPError(404)
121 info = os.stat(path)
120 info = os.stat(path)
122 last_modified = datetime.datetime.utcfromtimestamp(info.st_mtime)
121 last_modified = datetime.datetime.utcfromtimestamp(info.st_mtime)
123 with open(path,'r') as f:
122 with open(path,'r') as f:
124 s = f.read()
123 s = f.read()
125 try:
124 try:
126 # v1 and v2 and json in the .ipynb files.
125 # v1 and v2 and json in the .ipynb files.
127 nb = current.reads(s, u'json')
126 nb = current.reads(s, u'json')
128 except:
127 except:
129 raise web.HTTPError(404)
128 raise web.HTTPError(404)
130 if 'name' not in nb:
129 if 'name' not in nb:
131 nb.name = os.path.split(path)[-1].split(u'.')[0]
130 nb.name = os.path.split(path)[-1].split(u'.')[0]
132 return last_modified, nb
131 return last_modified, nb
133
132
134 def save_new_notebook(self, data, name=None, format=u'json'):
133 def save_new_notebook(self, data, name=None, format=u'json'):
135 """Save a new notebook and return its notebook_id.
134 """Save a new notebook and return its notebook_id.
136
135
137 If a name is passed in, it overrides any values in the notebook data
136 If a name is passed in, it overrides any values in the notebook data
138 and the value in the data is updated to use that value.
137 and the value in the data is updated to use that value.
139 """
138 """
140 if format not in self.allowed_formats:
139 if format not in self.allowed_formats:
141 raise web.HTTPError(415)
140 raise web.HTTPError(415)
142
141
143 try:
142 try:
144 nb = current.reads(data, format)
143 nb = current.reads(data, format)
145 except:
144 except:
146 raise web.HTTPError(400)
145 raise web.HTTPError(400)
147
146
148 if name is None:
147 if name is None:
149 try:
148 try:
150 name = nb.metadata.name
149 name = nb.metadata.name
151 except AttributeError:
150 except AttributeError:
152 raise web.HTTPError(400)
151 raise web.HTTPError(400)
153 nb.metadata.name = name
152 nb.metadata.name = name
154
153
155 notebook_id = self.new_notebook_id(name)
154 notebook_id = self.new_notebook_id(name)
156 self.save_notebook_object(notebook_id, nb)
155 self.save_notebook_object(notebook_id, nb)
157 return notebook_id
156 return notebook_id
158
157
159 def save_notebook(self, notebook_id, data, name=None, format=u'json'):
158 def save_notebook(self, notebook_id, data, name=None, format=u'json'):
160 """Save an existing notebook by notebook_id."""
159 """Save an existing notebook by notebook_id."""
161 if format not in self.allowed_formats:
160 if format not in self.allowed_formats:
162 raise web.HTTPError(415)
161 raise web.HTTPError(415)
163
162
164 try:
163 try:
165 nb = current.reads(data, format)
164 nb = current.reads(data, format)
166 except:
165 except:
167 raise web.HTTPError(400)
166 raise web.HTTPError(400)
168
167
169 if name is not None:
168 if name is not None:
170 nb.metadata.name = name
169 nb.metadata.name = name
171 self.save_notebook_object(notebook_id, nb)
170 self.save_notebook_object(notebook_id, nb)
172
171
173 def save_notebook_object(self, notebook_id, nb):
172 def save_notebook_object(self, notebook_id, nb):
174 """Save an existing notebook object by notebook_id."""
173 """Save an existing notebook object by notebook_id."""
175 if notebook_id not in self.mapping:
174 if notebook_id not in self.mapping:
176 raise web.HTTPError(404)
175 raise web.HTTPError(404)
177 old_name = self.mapping[notebook_id]
176 old_name = self.mapping[notebook_id]
178 try:
177 try:
179 new_name = nb.metadata.name
178 new_name = nb.metadata.name
180 except AttributeError:
179 except AttributeError:
181 raise web.HTTPError(400)
180 raise web.HTTPError(400)
182 path = self.get_path_by_name(new_name)
181 path = self.get_path_by_name(new_name)
183 try:
182 try:
184 with open(path,'w') as f:
183 with open(path,'w') as f:
185 current.write(nb, f, u'json')
184 current.write(nb, f, u'json')
186 except:
185 except:
187 raise web.HTTPError(400)
186 raise web.HTTPError(400)
188 if old_name != new_name:
187 if old_name != new_name:
189 old_path = self.get_path_by_name(old_name)
188 old_path = self.get_path_by_name(old_name)
190 if os.path.isfile(old_path):
189 if os.path.isfile(old_path):
191 os.unlink(old_path)
190 os.unlink(old_path)
192 self.mapping[notebook_id] = new_name
191 self.mapping[notebook_id] = new_name
193 self.rev_mapping[new_name] = notebook_id
192 self.rev_mapping[new_name] = notebook_id
194
193
195 def delete_notebook(self, notebook_id):
194 def delete_notebook(self, notebook_id):
196 """Delete notebook by notebook_id."""
195 """Delete notebook by notebook_id."""
197 path = self.find_path(notebook_id)
196 path = self.find_path(notebook_id)
198 if not os.path.isfile(path):
197 if not os.path.isfile(path):
199 raise web.HTTPError(404)
198 raise web.HTTPError(404)
200 os.unlink(path)
199 os.unlink(path)
201 self.delete_notebook_id(notebook_id)
200 self.delete_notebook_id(notebook_id)
202
201
203 def new_notebook(self):
202 def new_notebook(self):
204 """Create a new notebook and returns its notebook_id."""
203 """Create a new notebook and returns its notebook_id."""
205 i = 0
204 i = 0
206 while True:
205 while True:
207 name = u'Untitled%i' % i
206 name = u'Untitled%i' % i
208 path = self.get_path_by_name(name)
207 path = self.get_path_by_name(name)
209 if not os.path.isfile(path):
208 if not os.path.isfile(path):
210 break
209 break
211 else:
210 else:
212 i = i+1
211 i = i+1
213 notebook_id = self.new_notebook_id(name)
212 notebook_id = self.new_notebook_id(name)
214 metadata = current.new_metadata(name=name)
213 metadata = current.new_metadata(name=name)
215 nb = current.new_notebook(metadata=metadata)
214 nb = current.new_notebook(metadata=metadata)
216 with open(path,'w') as f:
215 with open(path,'w') as f:
217 current.write(nb, f, u'json')
216 current.write(nb, f, u'json')
218 return notebook_id
217 return notebook_id
219
218
@@ -1,203 +1,202
1 .. _htmlnotebook:
1 .. _htmlnotebook:
2
2
3 =========================
3 =========================
4 An HTML Notebook IPython
4 An HTML Notebook IPython
5 =========================
5 =========================
6
6
7 The IPython Notebook consists of two related components:
7 The IPython Notebook consists of two related components:
8
8
9 * An XML/JSON based Notebook document format for recording and distributing
9 * An JSON based Notebook document format for recording and distributing
10 Python code and rich text.
10 Python code and rich text.
11 * A web-based user interface for authoring and running notebook documents.
11 * A web-based user interface for authoring and running notebook documents.
12
12
13 The Notebook can be used by starting the Notebook server with the
13 The Notebook can be used by starting the Notebook server with the
14 command::
14 command::
15
15
16 $ ipython notebook
16 $ ipython notebook
17
17
18 Note that by default, the notebook doesn't load pylab, it's just a normal
18 Note that by default, the notebook doesn't load pylab, it's just a normal
19 IPython session like any other. If you want pylab support, you must use::
19 IPython session like any other. If you want pylab support, you must use::
20
20
21 $ ipython notebook --pylab
21 $ ipython notebook --pylab
22
22
23 which will behave similar to the terminal and Qt console versions, using your
23 which will behave similar to the terminal and Qt console versions, using your
24 default matplotlib backend and providing floating interactive plot windows. If
24 default matplotlib backend and providing floating interactive plot windows. If
25 you want inline figures, you must manually select the ``inline`` backend::
25 you want inline figures, you must manually select the ``inline`` backend::
26
26
27 $ ipython notebook --pylab inline
27 $ ipython notebook --pylab=inline
28
28
29 This server uses the same ZeroMQ-based two process kernel architecture as
29 This server uses the same ZeroMQ-based two process kernel architecture as
30 the QT Console as well Tornado for serving HTTP requests. Some of the main
30 the QT Console as well Tornado for serving HTTP requests. Some of the main
31 features of the Notebook include:
31 features of the Notebook include:
32
32
33 * Display rich data (png/html/latex/svg) in the browser as a result of
33 * Display rich data (png/html/latex/svg) in the browser as a result of
34 computations.
34 computations.
35 * Compose text cells using HTML and Markdown.
35 * Compose text cells using HTML and Markdown.
36 * Import and export notebook documents in range of formats (.ipynb, .json, .py).
36 * Import and export notebook documents in range of formats (.ipynb, .py).
37 * In browser syntax highlighting, tab completion and autoindentation.
37 * In browser syntax highlighting, tab completion and autoindentation.
38 * Inline matplotlib plots that can be stored in Notebook documents and opened
38 * Inline matplotlib plots that can be stored in Notebook documents and opened
39 later.
39 later.
40
40
41 See :ref:`our installation documentation <install_index>` for directions on
41 See :ref:`our installation documentation <install_index>` for directions on
42 how to install the notebook and its dependencies.
42 how to install the notebook and its dependencies.
43
43
44 .. note::
44 .. note::
45
45
46 You can start more than one notebook server at the same time, if you want to
46 You can start more than one notebook server at the same time, if you want to
47 work on notebooks in different directories. By default the first notebook
47 work on notebooks in different directories. By default the first notebook
48 server starts in port 8888, later notebooks search for random ports near
48 server starts in port 8888, later notebooks search for random ports near
49 that one. You can also manually specify the port with the ``--port``
49 that one. You can also manually specify the port with the ``--port``
50 option, if you want persistent URLs you can bookmark.
50 option.
51
51
52
52
53 Basic Usage
53 Basic Usage
54 ===========
54 ===========
55
55
56 The landing page of the notebook server application, which we call the IPython
56 The landing page of the notebook server application, which we call the IPython
57 Notebook *dashboard*, shows the notebooks currently available in the directory
57 Notebook *dashboard*, shows the notebooks currently available in the directory
58 in which the application was started, and allows you to create new notebooks.
58 in which the application was started, and allows you to create new notebooks.
59
59
60 A notebook is a combination of two things:
60 A notebook is a combination of two things:
61
61
62 1. an interactive session connected to an IPython kernel, controlled by a web
62 1. An interactive session connected to an IPython kernel, controlled by a web
63 application that can send input to the console and display many types of output
63 application that can send input to the console and display many types of output
64 (text, graphics, mathematics and more). This is the same kernel used by the
64 (text, graphics, mathematics and more). This is the same kernel used by the
65 :ref:`Qt console <qtconsole>`, but in this case the web console sends input in
65 :ref:`Qt console <qtconsole>`, but in this case the web console sends input in
66 persistent cells that you can edit in-place instead of the vertically scrolling
66 persistent cells that you can edit in-place instead of the vertically scrolling
67 terminal style used by the Qt console.
67 terminal style used by the Qt console.
68
68
69 2. a document that can save the inputs and outputs of the session as well as
69 2. A document that can save the inputs and outputs of the session as well as
70 additional text that accompanies the code but is not meant for execution. In
70 additional text that accompanies the code but is not meant for execution. In
71 this way, notebook files serve as a complete computational record of a session
71 this way, notebook files serve as a complete computational record of a session
72 including explanatory text and mathematics, code and resulting figures. These
72 including explanatory text and mathematics, code and resulting figures. These
73 documents are internally JSON files and are saved with the ``.ipynb``
73 documents are internally JSON files and are saved with the ``.ipynb``
74 extension.
74 extension.
75
75
76 If you have ever used the Mathematica or Sage notebooks (the latter is also
76 If you have ever used the Mathematica or Sage notebooks (the latter is also
77 web-based__) you should feel right at home. If you have not, you should be
77 web-based__) you should feel right at home. If you have not, you should be
78 able to learn how to use it in just a few minutes.
78 able to learn how to use it in just a few minutes.
79
79
80 .. __: http://sagenb.org
80 .. __: http://sagenb.org
81
81
82
82
83 Creating and editing notebooks
83 Creating and editing notebooks
84 ------------------------------
84 ------------------------------
85
85
86 You can create new notebooks from the dashboard with the ``New Notebook``
86 You can create new notebooks from the dashboard with the ``New Notebook``
87 button or open existing ones by clicking on their name. Once in a notebook,
87 button or open existing ones by clicking on their name. Once in a notebook,
88 your browser tab will reflect the name of that notebook (prefixed with "IPy:").
88 your browser tab will reflect the name of that notebook (prefixed with "IPy:").
89 The URL for that notebook is not meant to be human-readable, but it is
89 The URL for that notebook is not meant to be human-readable and is *not*
90 persistent across invocations of the notebook server *as long as you don't
90 persistent across invocations of the notebook server.
91 rename the notebook*, so you can bookmark them for future use.
92
91
93 You can also drag and dropp into the area listing files any python file: it
92 You can also drag and drop into the area listing files any python file: it
94 will be imported into a notebook with the same name (but ``.ipynb`` extension)
93 will be imported into a notebook with the same name (but ``.ipynb`` extension)
95 located in the directory where the notebook server was started. This notebook
94 located in the directory where the notebook server was started. This notebook
96 will consist of a single cell with all the code in the file, which you can
95 will consist of a single cell with all the code in the file, which you can
97 later manually partition into individual cells for gradual execution, add text
96 later manually partition into individual cells for gradual execution, add text
98 and graphics, etc.
97 and graphics, etc.
99
98
100 Workflow and limitations
99 Workflow and limitations
101 ------------------------
100 ------------------------
102
101
103 The normal workflow in a notebook is quite similar to a normal IPython session,
102 The normal workflow in a notebook is quite similar to a normal IPython session,
104 with the difference that you can edit a cell in-place multiple times until you
103 with the difference that you can edit a cell in-place multiple times until you
105 obtain the desired results rather than having to rerun separate scripts with
104 obtain the desired results rather than having to rerun separate scripts with
106 the ``%run`` magic (though magics also work in the notebook). Typically
105 the ``%run`` magic (though magics also work in the notebook). Typically
107 you'll work on a problem in pieces, organizing related pieces into cells and
106 you'll work on a problem in pieces, organizing related pieces into cells and
108 moving forward as previous parts work correctly. This is much more convenient
107 moving forward as previous parts work correctly. This is much more convenient
109 for interactive exploration than breaking up a computation into scripts that
108 for interactive exploration than breaking up a computation into scripts that
110 must be executed together, especially if parts of them take a long time to run
109 must be executed together, especially if parts of them take a long time to run
111 (you can use tricks with namespaces and ``%run -i``, but we think the notebook
110 (you can use tricks with namespaces and ``%run -i``, but we think the notebook
112 is a more natural solution for that kind of problem).
111 is a more natural solution for that kind of problem).
113
112
114 The only significant limitation the notebook currently has, compared to the qt
113 The only significant limitation the notebook currently has, compared to the qt
115 console, is that it can not run any code that expects input from the kernel
114 console, is that it can not run any code that expects input from the kernel
116 (such as scripts that call :func:`raw_input`). Very importantly, this means
115 (such as scripts that call :func:`raw_input`). Very importantly, this means
117 that the ``%debug`` magic does *not* work in the notebook! We intend to
116 that the ``%debug`` magic does *not* work in the notebook! We intend to
118 correct this limitation, but in the meantime, there is a way to debug problems
117 correct this limitation, but in the meantime, there is a way to debug problems
119 in the notebook: you can attach a Qt console to your existing notebook kernel,
118 in the notebook: you can attach a Qt console to your existing notebook kernel,
120 and run ``%debug`` from the Qt console. Simply look for the lines in the
119 and run ``%debug`` from the Qt console. Simply look for the lines in the
121 terminal where you started the kernel that read something like::
120 terminal where you started the kernel that read something like::
122
121
123 [IPKernelApp] To connect another client to this kernel, use:
122 [IPKernelApp] To connect another client to this kernel, use:
124 [IPKernelApp] --existing --shell=53328 --iopub=53817 --stdin=34736 --hb=45543
123 [IPKernelApp] --existing --shell=53328 --iopub=53817 --stdin=34736 --hb=45543
125
124
126 and then start a qt console pointing to that kernel::
125 and then start a qt console pointing to that kernel::
127
126
128 ipython qtconsole --existing --shell=53328 --iopub=53817 --stdin=34736 --hb=45543
127 ipython qtconsole --existing --shell=53328 --iopub=53817 --stdin=34736 --hb=45543
129
128
130
129
131 Text input
130 Text input
132 ----------
131 ----------
133
132
134 In addition to code cells and the output they procude (such as figures), you
133 In addition to code cells and the output they procude (such as figures), you
135 can also type text not meant for execution. To type text, change the type of a
134 can also type text not meant for execution. To type text, change the type of a
136 cell from ``Code`` to ``Markdown`` by using the button or the :kbd:`C-m m`
135 cell from ``Code`` to ``Markdown`` by using the button or the :kbd:`Ctrl-m m`
137 keybinding (see below). You can then type any text in Markdown_ syntax, as
136 keybinding (see below). You can then type any text in Markdown_ syntax, as
138 well as mathematical expressions if you use ``$...$`` for inline math or
137 well as mathematical expressions if you use ``$...$`` for inline math or
139 ``$$...$$`` for displayed math.
138 ``$$...$$`` for displayed math.
140
139
141 Exporting a notebook
140 Exporting a notebook
142 --------------------
141 --------------------
143
142
144 If you want to provide others with a static HTML or PDF view of your notebook,
143 If you want to provide others with a static HTML or PDF view of your notebook,
145 use the ``Print`` button. This opens a static view of the document, which you
144 use the ``Print`` button. This opens a static view of the document, which you
146 can print to PDF using your operating system's facilities, or save to a file
145 can print to PDF using your operating system's facilities, or save to a file
147 with your web browser's 'Save' option (note that typically, this will create
146 with your web browser's 'Save' option (note that typically, this will create
148 both an html file *and* a directory called `notebook_name_files` next to it
147 both an html file *and* a directory called `notebook_name_files` next to it
149 that contains all the necessary style information, so if you intend to share
148 that contains all the necessary style information, so if you intend to share
150 this, you must send the directory along with the main html file).
149 this, you must send the directory along with the main html file).
151
150
152 The `Download` button lets you save a notebook file to the Download area
151 The `Download` button lets you save a notebook file to the Download area
153 configured by your web browser (particularly useful if you are running the
152 configured by your web browser (particularly useful if you are running the
154 notebook server on a remote host and need a file locally). The notebook is
153 notebook server on a remote host and need a file locally). The notebook is
155 saved by default with the ``.ipynb`` extension and the files contain JSON data
154 saved by default with the ``.ipynb`` extension and the files contain JSON data
156 that is not meant for human editing or consumption. But you can always export
155 that is not meant for human editing or consumption. But you can always export
157 the input part of a notebook to a plain python script by choosing Python format
156 the input part of a notebook to a plain python script by choosing Python format
158 in the `Download` drop list. This removes all output and saves the text cells
157 in the `Download` drop list. This removes all output and saves the text cells
159 in comment areas.
158 in comment areas.
160
159
161 .. warning::
160 .. warning::
162
161
163 While in simple cases you can roundtrip a notebook to Python, edit the
162 While in simple cases you can roundtrip a notebook to Python, edit the
164 python file and import it back without loss, this is in general *not
163 python file and import it back without loss, this is in general *not
165 guaranteed to work at all*. As the notebook format evolves in complexity,
164 guaranteed to work at all*. As the notebook format evolves in complexity,
166 there will be attributes of the notebook that will not survive a roundtrip
165 there will be attributes of the notebook that will not survive a roundtrip
167 through the Python form. You should think of the Python format as a way to
166 through the Python form. You should think of the Python format as a way to
168 output a script version of a notebook and the import capabilities as a way
167 output a script version of a notebook and the import capabilities as a way
169 to load existing code to get a notebook started. But the Python version is
168 to load existing code to get a notebook started. But the Python version is
170 *not* an alternate Python format.
169 *not* an alternate notebook format.
171
170
172
171
173 Keyboard use
172 Keyboard use
174 ------------
173 ------------
175
174
176 All actions in the notebook can be achieved with the mouse, but we have also
175 All actions in the notebook can be achieved with the mouse, but we have also
177 added keyboard shortcuts for the most common ones, so that productive use of
176 added keyboard shortcuts for the most common ones, so that productive use of
178 the notebook can be achieved with minimal mouse intervention. The main
177 the notebook can be achieved with minimal mouse intervention. The main
179 key bindings you need to remember are:
178 key bindings you need to remember are:
180
179
181 * :kbd:`Shift-Enter`: execute the current cell (similar to the Qt console),
180 * :kbd:`Shift-Enter`: execute the current cell (similar to the Qt console),
182 show output (if any) and create a new cell below. Note that in the notebook,
181 show output (if any) and create a new cell below. Note that in the notebook,
183 simply using :kbd:`Enter` *never* forces execution, it simply inserts a new
182 simply using :kbd:`Enter` *never* forces execution, it simply inserts a new
184 line in the current cell. Therefore, in the notebook you must always use
183 line in the current cell. Therefore, in the notebook you must always use
185 :kbd:`Shift-Enter` to get execution (or use the mouse and click on the ``Run
184 :kbd:`Shift-Enter` to get execution (or use the mouse and click on the ``Run
186 Selected`` button).
185 Selected`` button).
187
186
188 * :kbd:`Control-Enter`: execute the current cell in "terminal mode", where any
187 * :kbd:`Ctrl-Enter`: execute the current cell in "terminal mode", where any
189 output is shown but the cursor cursor stays in the current cell, whose input
188 output is shown but the cursor cursor stays in the current cell, whose input
190 area is flushed empty. This is convenient to do quick in-place experiments
189 area is flushed empty. This is convenient to do quick in-place experiments
191 or query things like filesystem content without creating additional cells you
190 or query things like filesystem content without creating additional cells you
192 may not want saved in your notebook.
191 may not want saved in your notebook.
193
192
194 * :kbd:`Control-m`: this is the prefix for all other keybindings, which consist
193 * :kbd:`Ctrl-m`: this is the prefix for all other keybindings, which consist
195 of an additional single letter. Type :kbd:`Ctrl-m h` (that is, the sole
194 of an additional single letter. Type :kbd:`Ctrl-m h` (that is, the sole
196 letter :kbd:`h` after :kbd:`Ctrl-m`) and IPython will show you the remaining
195 letter :kbd:`h` after :kbd:`Ctrl-m`) and IPython will show you the remaining
197 available keybindings.
196 available keybindings.
198
197
199
198
200 Notebook document format
199 Notebook document format
201 ========================
200 ========================
202
201
203
202
General Comments 0
You need to be logged in to leave comments. Login now