##// END OF EJS Templates
strip transient values to/from nb files...
MinRK -
Show More
@@ -1,346 +1,346 b''
1 {
1 {
2 "$schema": "http://json-schema.org/draft-04/schema#",
2 "$schema": "http://json-schema.org/draft-04/schema#",
3 "description": "IPython Notebook v4.0 JSON schema.",
3 "description": "IPython Notebook v4.0 JSON schema.",
4 "type": "object",
4 "type": "object",
5 "additionalProperties": false,
5 "additionalProperties": false,
6 "required": ["metadata", "nbformat_minor", "nbformat", "cells"],
6 "required": ["metadata", "nbformat_minor", "nbformat", "cells"],
7 "properties": {
7 "properties": {
8 "metadata": {
8 "metadata": {
9 "description": "Notebook root-level metadata.",
9 "description": "Notebook root-level metadata.",
10 "type": "object",
10 "type": "object",
11 "additionalProperties": true,
11 "additionalProperties": true,
12 "properties": {
12 "properties": {
13 "kernel_info": {
13 "kernel_info": {
14 "description": "Kernel information.",
14 "description": "Kernel information.",
15 "type": "object",
15 "type": "object",
16 "required": ["name", "language"],
16 "required": ["name", "language"],
17 "properties": {
17 "properties": {
18 "name": {
18 "name": {
19 "description": "Name of the kernel specification.",
19 "description": "Name of the kernel specification.",
20 "type": "string"
20 "type": "string"
21 },
21 },
22 "language": {
22 "language": {
23 "description": "The programming language which this kernel runs.",
23 "description": "The programming language which this kernel runs.",
24 "type": "string"
24 "type": "string"
25 },
25 },
26 "codemirror_mode": {
26 "codemirror_mode": {
27 "description": "The codemirror mode to use for code in this language.",
27 "description": "The codemirror mode to use for code in this language.",
28 "type": "string"
28 "type": "string"
29 }
29 }
30 }
30 }
31 },
31 },
32 "signature": {
32 "signature": {
33 "description": "Hash of the notebook.",
33 "description": "Hash of the notebook.",
34 "type": "string"
34 "type": "string"
35 },
35 },
36 "orig_nbformat": {
36 "orig_nbformat": {
37 "description": "Original notebook format (major number) before converting the notebook between versions.",
37 "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.",
38 "type": "integer",
38 "type": "integer",
39 "minimum": 1
39 "minimum": 1
40 }
40 }
41 }
41 }
42 },
42 },
43 "nbformat_minor": {
43 "nbformat_minor": {
44 "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.",
44 "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.",
45 "type": "integer",
45 "type": "integer",
46 "minimum": 0
46 "minimum": 0
47 },
47 },
48 "nbformat": {
48 "nbformat": {
49 "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.",
49 "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.",
50 "type": "integer",
50 "type": "integer",
51 "minimum": 4,
51 "minimum": 4,
52 "maximum": 4
52 "maximum": 4
53 },
53 },
54 "cells": {
54 "cells": {
55 "description": "Array of cells of the current notebook.",
55 "description": "Array of cells of the current notebook.",
56 "type": "array",
56 "type": "array",
57 "items": {
57 "items": {
58 "type": "object",
58 "type": "object",
59 "oneOf": [
59 "oneOf": [
60 {"$ref": "#/definitions/raw_cell"},
60 {"$ref": "#/definitions/raw_cell"},
61 {"$ref": "#/definitions/markdown_cell"},
61 {"$ref": "#/definitions/markdown_cell"},
62 {"$ref": "#/definitions/heading_cell"},
62 {"$ref": "#/definitions/heading_cell"},
63 {"$ref": "#/definitions/code_cell"}
63 {"$ref": "#/definitions/code_cell"}
64 ]
64 ]
65 }
65 }
66 }
66 }
67 },
67 },
68
68
69 "definitions": {
69 "definitions": {
70
70
71 "raw_cell": {
71 "raw_cell": {
72 "description": "Notebook raw nbconvert cell.",
72 "description": "Notebook raw nbconvert cell.",
73 "type": "object",
73 "type": "object",
74 "additionalProperties": false,
74 "additionalProperties": false,
75 "required": ["cell_type", "metadata", "source"],
75 "required": ["cell_type", "metadata", "source"],
76 "properties": {
76 "properties": {
77 "cell_type": {
77 "cell_type": {
78 "description": "String identifying the type of cell.",
78 "description": "String identifying the type of cell.",
79 "enum": ["raw"]
79 "enum": ["raw"]
80 },
80 },
81 "metadata": {
81 "metadata": {
82 "description": "Cell-level metadata.",
82 "description": "Cell-level metadata.",
83 "type": "object",
83 "type": "object",
84 "additionalProperties": true,
84 "additionalProperties": true,
85 "properties": {
85 "properties": {
86 "format": {
86 "format": {
87 "description": "Raw cell metadata format for nbconvert.",
87 "description": "Raw cell metadata format for nbconvert.",
88 "type": "string"
88 "type": "string"
89 },
89 },
90 "name": {"$ref": "#/definitions/misc/metadata_name"},
90 "name": {"$ref": "#/definitions/misc/metadata_name"},
91 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
91 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
92 }
92 }
93 },
93 },
94 "source": {"$ref": "#/definitions/misc/source"}
94 "source": {"$ref": "#/definitions/misc/source"}
95 }
95 }
96 },
96 },
97
97
98 "markdown_cell": {
98 "markdown_cell": {
99 "description": "Notebook markdown cell.",
99 "description": "Notebook markdown cell.",
100 "type": "object",
100 "type": "object",
101 "additionalProperties": false,
101 "additionalProperties": false,
102 "required": ["cell_type", "metadata", "source"],
102 "required": ["cell_type", "metadata", "source"],
103 "properties": {
103 "properties": {
104 "cell_type": {
104 "cell_type": {
105 "description": "String identifying the type of cell.",
105 "description": "String identifying the type of cell.",
106 "enum": ["markdown"]
106 "enum": ["markdown"]
107 },
107 },
108 "metadata": {
108 "metadata": {
109 "description": "Cell-level metadata.",
109 "description": "Cell-level metadata.",
110 "type": "object",
110 "type": "object",
111 "properties": {
111 "properties": {
112 "name": {"$ref": "#/definitions/misc/metadata_name"},
112 "name": {"$ref": "#/definitions/misc/metadata_name"},
113 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
113 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
114 },
114 },
115 "additionalProperties": true
115 "additionalProperties": true
116 },
116 },
117 "source": {"$ref": "#/definitions/misc/source"}
117 "source": {"$ref": "#/definitions/misc/source"}
118 }
118 }
119 },
119 },
120
120
121 "heading_cell": {
121 "heading_cell": {
122 "description": "Notebook heading cell.",
122 "description": "Notebook heading cell.",
123 "type": "object",
123 "type": "object",
124 "additionalProperties": false,
124 "additionalProperties": false,
125 "required": ["cell_type", "metadata", "source", "level"],
125 "required": ["cell_type", "metadata", "source", "level"],
126 "properties": {
126 "properties": {
127 "cell_type": {
127 "cell_type": {
128 "description": "String identifying the type of cell.",
128 "description": "String identifying the type of cell.",
129 "enum": ["heading"]
129 "enum": ["heading"]
130 },
130 },
131 "metadata": {
131 "metadata": {
132 "description": "Cell-level metadata.",
132 "description": "Cell-level metadata.",
133 "type": "object",
133 "type": "object",
134 "properties": {
134 "properties": {
135 "name": {"$ref": "#/definitions/misc/metadata_name"},
135 "name": {"$ref": "#/definitions/misc/metadata_name"},
136 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
136 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
137 },
137 },
138 "additionalProperties": true
138 "additionalProperties": true
139 },
139 },
140 "source": {"$ref": "#/definitions/misc/source"},
140 "source": {"$ref": "#/definitions/misc/source"},
141 "level": {
141 "level": {
142 "description": "Level of heading cells.",
142 "description": "Level of heading cells.",
143 "type": "integer",
143 "type": "integer",
144 "minimum": 1
144 "minimum": 1
145 }
145 }
146 }
146 }
147 },
147 },
148
148
149 "code_cell": {
149 "code_cell": {
150 "description": "Notebook code cell.",
150 "description": "Notebook code cell.",
151 "type": "object",
151 "type": "object",
152 "additionalProperties": false,
152 "additionalProperties": false,
153 "required": ["cell_type", "metadata", "source", "outputs", "prompt_number"],
153 "required": ["cell_type", "metadata", "source", "outputs", "prompt_number"],
154 "properties": {
154 "properties": {
155 "cell_type": {
155 "cell_type": {
156 "description": "String identifying the type of cell.",
156 "description": "String identifying the type of cell.",
157 "enum": ["code"]
157 "enum": ["code"]
158 },
158 },
159 "metadata": {
159 "metadata": {
160 "description": "Cell-level metadata.",
160 "description": "Cell-level metadata.",
161 "type": "object",
161 "type": "object",
162 "additionalProperties": true,
162 "additionalProperties": true,
163 "properties": {
163 "properties": {
164 "collapsed": {
164 "collapsed": {
165 "description": "Whether the cell is collapsed/expanded.",
165 "description": "Whether the cell is collapsed/expanded.",
166 "type": "boolean"
166 "type": "boolean"
167 },
167 },
168 "autoscroll": {
168 "autoscroll": {
169 "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.",
169 "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.",
170 "enum": [true, false, "auto"]
170 "enum": [true, false, "auto"]
171 },
171 },
172 "name": {"$ref": "#/definitions/misc/metadata_name"},
172 "name": {"$ref": "#/definitions/misc/metadata_name"},
173 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
173 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
174 }
174 }
175 },
175 },
176 "source": {"$ref": "#/definitions/misc/source"},
176 "source": {"$ref": "#/definitions/misc/source"},
177 "outputs": {
177 "outputs": {
178 "description": "Execution, display, or stream outputs.",
178 "description": "Execution, display, or stream outputs.",
179 "type": "array",
179 "type": "array",
180 "items": {"$ref": "#/definitions/output"}
180 "items": {"$ref": "#/definitions/output"}
181 },
181 },
182 "prompt_number": {
182 "prompt_number": {
183 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
183 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
184 "type": ["integer", "null"],
184 "type": ["integer", "null"],
185 "minimum": 0
185 "minimum": 0
186 }
186 }
187 }
187 }
188 },
188 },
189 "output": {
189 "output": {
190 "type": "object",
190 "type": "object",
191 "oneOf": [
191 "oneOf": [
192 {"$ref": "#/definitions/execute_result"},
192 {"$ref": "#/definitions/execute_result"},
193 {"$ref": "#/definitions/display_data"},
193 {"$ref": "#/definitions/display_data"},
194 {"$ref": "#/definitions/stream"},
194 {"$ref": "#/definitions/stream"},
195 {"$ref": "#/definitions/error"}
195 {"$ref": "#/definitions/error"}
196 ]
196 ]
197 },
197 },
198 "execute_result": {
198 "execute_result": {
199 "description": "Result of executing a code cell.",
199 "description": "Result of executing a code cell.",
200 "type": "object",
200 "type": "object",
201 "additionalProperties": false,
201 "additionalProperties": false,
202 "required": ["output_type", "metadata", "prompt_number"],
202 "required": ["output_type", "metadata", "prompt_number"],
203 "properties": {
203 "properties": {
204 "output_type": {
204 "output_type": {
205 "description": "Type of cell output.",
205 "description": "Type of cell output.",
206 "enum": ["execute_result"]
206 "enum": ["execute_result"]
207 },
207 },
208 "prompt_number": {
208 "prompt_number": {
209 "description": "A result's prompt number.",
209 "description": "A result's prompt number.",
210 "type": ["integer"],
210 "type": ["integer"],
211 "minimum": 0
211 "minimum": 0
212 },
212 },
213 "application/json": {
213 "application/json": {
214 "type": "object"
214 "type": "object"
215 },
215 },
216 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
216 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
217 },
217 },
218 "patternProperties": {
218 "patternProperties": {
219 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
219 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
220 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
220 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
221 "$ref": "#/definitions/misc/multiline_string"
221 "$ref": "#/definitions/misc/multiline_string"
222 }
222 }
223 }
223 }
224 },
224 },
225
225
226 "display_data": {
226 "display_data": {
227 "description": "Data displayed as a result of code cell execution.",
227 "description": "Data displayed as a result of code cell execution.",
228 "type": "object",
228 "type": "object",
229 "additionalProperties": false,
229 "additionalProperties": false,
230 "required": ["output_type", "metadata"],
230 "required": ["output_type", "metadata"],
231 "properties": {
231 "properties": {
232 "output_type": {
232 "output_type": {
233 "description": "Type of cell output.",
233 "description": "Type of cell output.",
234 "enum": ["display_data"]
234 "enum": ["display_data"]
235 },
235 },
236 "application/json": {
236 "application/json": {
237 "type": "object"
237 "type": "object"
238 },
238 },
239 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
239 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
240 },
240 },
241 "patternProperties": {
241 "patternProperties": {
242 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
242 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
243 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
243 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
244 "$ref": "#/definitions/misc/multiline_string"
244 "$ref": "#/definitions/misc/multiline_string"
245 }
245 }
246 }
246 }
247 },
247 },
248
248
249 "stream": {
249 "stream": {
250 "description": "Stream output from a code cell.",
250 "description": "Stream output from a code cell.",
251 "type": "object",
251 "type": "object",
252 "additionalProperties": false,
252 "additionalProperties": false,
253 "required": ["output_type", "metadata", "name", "text"],
253 "required": ["output_type", "metadata", "name", "text"],
254 "properties": {
254 "properties": {
255 "output_type": {
255 "output_type": {
256 "description": "Type of cell output.",
256 "description": "Type of cell output.",
257 "enum": ["stream"]
257 "enum": ["stream"]
258 },
258 },
259 "metadata": {"$ref": "#/definitions/misc/output_metadata"},
259 "metadata": {"$ref": "#/definitions/misc/output_metadata"},
260 "name": {
260 "name": {
261 "description": "The name of the stream (stdout, stderr).",
261 "description": "The name of the stream (stdout, stderr).",
262 "type": "string"
262 "type": "string"
263 },
263 },
264 "text": {
264 "text": {
265 "description": "The stream's text output, represented as an array of strings.",
265 "description": "The stream's text output, represented as an array of strings.",
266 "$ref": "#/definitions/misc/multiline_string"
266 "$ref": "#/definitions/misc/multiline_string"
267 }
267 }
268 }
268 }
269 },
269 },
270
270
271 "error": {
271 "error": {
272 "description": "Output of an error that occurred during code cell execution.",
272 "description": "Output of an error that occurred during code cell execution.",
273 "type": "object",
273 "type": "object",
274 "additionalProperties": false,
274 "additionalProperties": false,
275 "required": ["output_type", "metadata", "ename", "evalue", "traceback"],
275 "required": ["output_type", "metadata", "ename", "evalue", "traceback"],
276 "properties": {
276 "properties": {
277 "output_type": {
277 "output_type": {
278 "description": "Type of cell output.",
278 "description": "Type of cell output.",
279 "enum": ["error"]
279 "enum": ["error"]
280 },
280 },
281 "metadata": {"$ref": "#/definitions/misc/output_metadata"},
281 "metadata": {"$ref": "#/definitions/misc/output_metadata"},
282 "ename": {
282 "ename": {
283 "description": "The name of the error.",
283 "description": "The name of the error.",
284 "type": "string"
284 "type": "string"
285 },
285 },
286 "evalue": {
286 "evalue": {
287 "description": "The value, or message, of the error.",
287 "description": "The value, or message, of the error.",
288 "type": "string"
288 "type": "string"
289 },
289 },
290 "traceback": {
290 "traceback": {
291 "description": "The error's traceback, represented as an array of strings.",
291 "description": "The error's traceback, represented as an array of strings.",
292 "type": "array",
292 "type": "array",
293 "items": {"type": "string"}
293 "items": {"type": "string"}
294 }
294 }
295 }
295 }
296 },
296 },
297
297
298 "misc": {
298 "misc": {
299 "metadata_name": {
299 "metadata_name": {
300 "description": "The cell's name. If present, must be a non-empty string.",
300 "description": "The cell's name. If present, must be a non-empty string.",
301 "type": "string",
301 "type": "string",
302 "pattern": "^.+$"
302 "pattern": "^.+$"
303 },
303 },
304 "metadata_tags": {
304 "metadata_tags": {
305 "description": "The cell's tags. Tags must be unique, and must not contain commas.",
305 "description": "The cell's tags. Tags must be unique, and must not contain commas.",
306 "type": "array",
306 "type": "array",
307 "uniqueItems": true,
307 "uniqueItems": true,
308 "items": {
308 "items": {
309 "type": "string",
309 "type": "string",
310 "pattern": "^[^,]+$"
310 "pattern": "^[^,]+$"
311 }
311 }
312 },
312 },
313 "source": {
313 "source": {
314 "description": "Contents of the cell, represented as an array of lines.",
314 "description": "Contents of the cell, represented as an array of lines.",
315 "$ref": "#/definitions/misc/multiline_string"
315 "$ref": "#/definitions/misc/multiline_string"
316 },
316 },
317 "prompt_number": {
317 "prompt_number": {
318 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
318 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
319 "type": ["integer", "null"],
319 "type": ["integer", "null"],
320 "minimum": 0
320 "minimum": 0
321 },
321 },
322 "mimetype": {
322 "mimetype": {
323 "patternProperties": {
323 "patternProperties": {
324 "^[a-zA-Z0-9\\-\\+]+/[a-zA-Z0-9\\-\\+]+": {
324 "^[a-zA-Z0-9\\-\\+]+/[a-zA-Z0-9\\-\\+]+": {
325 "description": "The cell's mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
325 "description": "The cell's mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
326 "$ref": "#/definitions/misc/multiline_string"
326 "$ref": "#/definitions/misc/multiline_string"
327 }
327 }
328 }
328 }
329 },
329 },
330 "output_metadata": {
330 "output_metadata": {
331 "description": "Cell output metadata.",
331 "description": "Cell output metadata.",
332 "type": "object",
332 "type": "object",
333 "additionalProperties": true
333 "additionalProperties": true
334 },
334 },
335 "multiline_string": {
335 "multiline_string": {
336 "oneOf" : [
336 "oneOf" : [
337 {"type": "string"},
337 {"type": "string"},
338 {
338 {
339 "type": "array",
339 "type": "array",
340 "items": {"type": "string"}
340 "items": {"type": "string"}
341 }
341 }
342 ]
342 ]
343 }
343 }
344 }
344 }
345 }
345 }
346 }
346 }
@@ -1,55 +1,60 b''
1 """Read and write notebooks in JSON format."""
1 """Read and write notebooks in JSON format."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import copy
6 import copy
7 import json
7 import json
8
8
9 from IPython.utils import py3compat
9 from IPython.utils import py3compat
10
10
11 from .nbbase import from_dict
11 from .nbbase import from_dict
12 from .rwbase import (
12 from .rwbase import (
13 NotebookReader, NotebookWriter, rejoin_lines, split_lines
13 NotebookReader, NotebookWriter, rejoin_lines, split_lines, strip_transient
14 )
14 )
15
15
16
16
17 class BytesEncoder(json.JSONEncoder):
17 class BytesEncoder(json.JSONEncoder):
18 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
18 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
19 def default(self, obj):
19 def default(self, obj):
20 if isinstance(obj, bytes):
20 if isinstance(obj, bytes):
21 return obj.decode('ascii')
21 return obj.decode('ascii')
22 return json.JSONEncoder.default(self, obj)
22 return json.JSONEncoder.default(self, obj)
23
23
24
24
25 class JSONReader(NotebookReader):
25 class JSONReader(NotebookReader):
26
26
27 def reads(self, s, **kwargs):
27 def reads(self, s, **kwargs):
28 nb = json.loads(s, **kwargs)
28 nb = json.loads(s, **kwargs)
29 nb = self.to_notebook(nb, **kwargs)
29 nb = self.to_notebook(nb, **kwargs)
30 return nb
30 return nb
31
31
32 def to_notebook(self, d, **kwargs):
32 def to_notebook(self, d, **kwargs):
33 return rejoin_lines(from_dict(d))
33 nb = rejoin_lines(from_dict(d))
34 nb = strip_transient(nb)
35 return nb
34
36
35
37
36 class JSONWriter(NotebookWriter):
38 class JSONWriter(NotebookWriter):
37
39
38 def writes(self, nb, **kwargs):
40 def writes(self, nb, **kwargs):
39 kwargs['cls'] = BytesEncoder
41 kwargs['cls'] = BytesEncoder
40 kwargs['indent'] = 1
42 kwargs['indent'] = 1
41 kwargs['sort_keys'] = True
43 kwargs['sort_keys'] = True
42 kwargs['separators'] = (',',': ')
44 kwargs['separators'] = (',',': ')
45 # don't modify in-memory dict
46 nb = copy.deepcopy(nb)
43 if kwargs.pop('split_lines', True):
47 if kwargs.pop('split_lines', True):
44 nb = split_lines(copy.deepcopy(nb))
48 nb = split_lines(nb)
49 nb = strip_transient(nb)
45 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
50 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
46
51
47
52
48 _reader = JSONReader()
53 _reader = JSONReader()
49 _writer = JSONWriter()
54 _writer = JSONWriter()
50
55
51 reads = _reader.reads
56 reads = _reader.reads
52 read = _reader.read
57 read = _reader.read
53 to_notebook = _reader.to_notebook
58 to_notebook = _reader.to_notebook
54 write = _writer.write
59 write = _writer.write
55 writes = _writer.writes
60 writes = _writer.writes
@@ -1,106 +1,118 b''
1 """Base classes and utilities for readers and writers."""
1 """Base classes and utilities for readers and writers."""
2
2
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from IPython.utils import py3compat
6 from IPython.utils import py3compat
7 from IPython.utils.py3compat import unicode_type, string_types
7 from IPython.utils.py3compat import unicode_type, string_types
8
8
9 # output keys that are likely to have multiline values
9 # output keys that are likely to have multiline values
10 _multiline_outputs = {
10 _multiline_outputs = {
11 'text/plain',
11 'text/plain',
12 'text/html',
12 'text/html',
13 'image/svg+xml',
13 'image/svg+xml',
14 'text/latex',
14 'text/latex',
15 'application/javascript',
15 'application/javascript',
16 }
16 }
17
17
18
18
19 # FIXME: workaround for old splitlines()
19 # FIXME: workaround for old splitlines()
20 def _join_lines(lines):
20 def _join_lines(lines):
21 """join lines that have been written by splitlines()
21 """join lines that have been written by splitlines()
22
22
23 Has logic to protect against `splitlines()`, which
23 Has logic to protect against `splitlines()`, which
24 should have been `splitlines(True)`
24 should have been `splitlines(True)`
25 """
25 """
26 if lines and lines[0].endswith(('\n', '\r')):
26 if lines and lines[0].endswith(('\n', '\r')):
27 # created by splitlines(True)
27 # created by splitlines(True)
28 return u''.join(lines)
28 return u''.join(lines)
29 else:
29 else:
30 # created by splitlines()
30 # created by splitlines()
31 return u'\n'.join(lines)
31 return u'\n'.join(lines)
32
32
33
33
34 def rejoin_lines(nb):
34 def rejoin_lines(nb):
35 """rejoin multiline text into strings
35 """rejoin multiline text into strings
36
36
37 For reversing effects of ``split_lines(nb)``.
37 For reversing effects of ``split_lines(nb)``.
38
38
39 This only rejoins lines that have been split, so if text objects were not split
39 This only rejoins lines that have been split, so if text objects were not split
40 they will pass through unchanged.
40 they will pass through unchanged.
41
41
42 Used when reading JSON files that may have been passed through split_lines.
42 Used when reading JSON files that may have been passed through split_lines.
43 """
43 """
44 for cell in nb.cells:
44 for cell in nb.cells:
45 if 'source' in cell and isinstance(cell.source, list):
45 if 'source' in cell and isinstance(cell.source, list):
46 cell.source = _join_lines(cell.source)
46 cell.source = _join_lines(cell.source)
47 if cell.cell_type == 'code':
47 if cell.cell_type == 'code':
48 for output in cell.outputs:
48 for output in cell.outputs:
49 for key in _multiline_outputs:
49 for key in _multiline_outputs:
50 item = output.get(key, None)
50 item = output.get(key, None)
51 if isinstance(item, list):
51 if isinstance(item, list):
52 output[key] = _join_lines(item)
52 output[key] = _join_lines(item)
53 return nb
53 return nb
54
54
55
55
56 def split_lines(nb):
56 def split_lines(nb):
57 """split likely multiline text into lists of strings
57 """split likely multiline text into lists of strings
58
58
59 For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will
59 For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will
60 reverse the effects of ``split_lines(nb)``.
60 reverse the effects of ``split_lines(nb)``.
61
61
62 Used when writing JSON files.
62 Used when writing JSON files.
63 """
63 """
64 for cell in nb.cells:
64 for cell in nb.cells:
65 source = cell.get('source', None)
65 source = cell.get('source', None)
66 if isinstance(source, string_types):
66 if isinstance(source, string_types):
67 cell['source'] = source.splitlines(True)
67 cell['source'] = source.splitlines(True)
68
68
69 if cell.cell_type == 'code':
69 if cell.cell_type == 'code':
70 for output in cell.outputs:
70 for output in cell.outputs:
71 for key in _multiline_outputs:
71 for key in _multiline_outputs:
72 item = output.get(key, None)
72 item = output.get(key, None)
73 if isinstance(item, string_types):
73 if isinstance(item, string_types):
74 output[key] = item.splitlines(True)
74 output[key] = item.splitlines(True)
75 return nb
75 return nb
76
76
77
77
78 def strip_transient(nb):
79 """Strip transient values that shouldn't be stored in files.
80
81 This should be called in *both* read and write.
82 """
83 nb.metadata.pop('orig_nbformat', None)
84 nb.metadata.pop('orig_nbformat_minor', None)
85 for cell in nb.cells:
86 cell.metadata.pop('trusted', None)
87 return nb
88
89
78 class NotebookReader(object):
90 class NotebookReader(object):
79 """A class for reading notebooks."""
91 """A class for reading notebooks."""
80
92
81 def reads(self, s, **kwargs):
93 def reads(self, s, **kwargs):
82 """Read a notebook from a string."""
94 """Read a notebook from a string."""
83 raise NotImplementedError("loads must be implemented in a subclass")
95 raise NotImplementedError("loads must be implemented in a subclass")
84
96
85 def read(self, fp, **kwargs):
97 def read(self, fp, **kwargs):
86 """Read a notebook from a file like object"""
98 """Read a notebook from a file like object"""
87 nbs = fp.read()
99 nbs = fp.read()
88 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
100 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
89 nbs = py3compat.str_to_unicode(nbs)
101 nbs = py3compat.str_to_unicode(nbs)
90 return self.reads(nbs, **kwargs)
102 return self.reads(nbs, **kwargs)
91
103
92
104
93 class NotebookWriter(object):
105 class NotebookWriter(object):
94 """A class for writing notebooks."""
106 """A class for writing notebooks."""
95
107
96 def writes(self, nb, **kwargs):
108 def writes(self, nb, **kwargs):
97 """Write a notebook to a string."""
109 """Write a notebook to a string."""
98 raise NotImplementedError("loads must be implemented in a subclass")
110 raise NotImplementedError("loads must be implemented in a subclass")
99
111
100 def write(self, nb, fp, **kwargs):
112 def write(self, nb, fp, **kwargs):
101 """Write a notebook to a file like object"""
113 """Write a notebook to a file like object"""
102 nbs = self.writes(nb,**kwargs)
114 nbs = self.writes(nb,**kwargs)
103 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
115 if not py3compat.PY3 and not isinstance(nbs, unicode_type):
104 # this branch is likely only taken for JSON on Python 2
116 # this branch is likely only taken for JSON on Python 2
105 nbs = py3compat.str_to_unicode(nbs)
117 nbs = py3compat.str_to_unicode(nbs)
106 return fp.write(nbs)
118 return fp.write(nbs)
General Comments 0
You need to be logged in to leave comments. Login now