##// END OF EJS Templates
Add preprocessor that clears cell outputs
Julia Evans -
Show More
@@ -0,0 +1,32 b''
1 """Module containing a preprocessor that removes the outputs from code cells"""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
15 from .base import Preprocessor
16
17
18 #-----------------------------------------------------------------------------
19 # Classes
20 #-----------------------------------------------------------------------------
21 class ClearOutputPreprocessor(Preprocessor):
22 """
23 Removes the output from all code cells in a notebook.
24 """
25
26 def preprocess_cell(self, cell, resources, cell_index):
27 """
28 Apply a transformation on each cell. See base.py for details.
29 """
30 if cell.cell_type == 'code':
31 cell.outputs = []
32 return cell, resources
@@ -0,0 +1,46 b''
1 """
2 Module with tests for the clearoutput preprocessor.
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 from IPython.nbformat import current as nbformat
17
18 from .base import PreprocessorTestsBase
19 from ..clearoutput import ClearOutputPreprocessor
20
21
22 #-----------------------------------------------------------------------------
23 # Class
24 #-----------------------------------------------------------------------------
25
26 class TestClearOutput(PreprocessorTestsBase):
27 """Contains test functions for clearoutput.py"""
28
29
30 def build_preprocessor(self):
31 """Make an instance of a preprocessor"""
32 preprocessor = ClearOutputPreprocessor()
33 preprocessor.enabled = True
34 return preprocessor
35
36 def test_constructor(self):
37 """Can a ClearOutputPreprocessor be constructed?"""
38 self.build_preprocessor()
39
40 def test_output(self):
41 """Test the output of the ClearOutputPreprocessor"""
42 nb = self.build_notebook()
43 res = self.build_resources()
44 preprocessor = self.build_preprocessor()
45 nb, res = preprocessor(nb, res)
46 assert nb.worksheets[0].cells[0].outputs == []
@@ -1,275 +1,276 b''
1 1 """This module defines a base Exporter class. For Jinja template-based export,
2 2 see templateexporter.py.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from __future__ import print_function, absolute_import
18 18
19 19 # Stdlib imports
20 20 import io
21 21 import os
22 22 import copy
23 23 import collections
24 24 import datetime
25 25
26 26
27 27 # IPython imports
28 28 from IPython.config.configurable import LoggingConfigurable
29 29 from IPython.config import Config
30 30 from IPython.nbformat import current as nbformat
31 31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
32 32 from IPython.utils.importstring import import_item
33 33 from IPython.utils import text, py3compat
34 34
35 35 #-----------------------------------------------------------------------------
36 36 # Class
37 37 #-----------------------------------------------------------------------------
38 38
39 39 class ResourcesDict(collections.defaultdict):
40 40 def __missing__(self, key):
41 41 return ''
42 42
43 43
44 44 class Exporter(LoggingConfigurable):
45 45 """
46 46 Class containing methods that sequentially run a list of preprocessors on a
47 47 NotebookNode object and then return the modified NotebookNode object and
48 48 accompanying resources dict.
49 49 """
50 50
51 51 file_extension = Unicode(
52 52 'txt', config=True,
53 53 help="Extension of the file that should be written to disk"
54 54 )
55 55
56 56 # MIME type of the result file, for HTTP response headers.
57 57 # This is *not* a traitlet, because we want to be able to access it from
58 58 # the class, not just on instances.
59 59 output_mimetype = ''
60 60
61 61 #Configurability, allows the user to easily add filters and preprocessors.
62 62 preprocessors = List(config=True,
63 63 help="""List of preprocessors, by name or namespace, to enable.""")
64 64
65 65 _preprocessors = List()
66 66
67 67 default_preprocessors = List(['IPython.nbconvert.preprocessors.coalesce_streams',
68 68 'IPython.nbconvert.preprocessors.SVG2PDFPreprocessor',
69 69 'IPython.nbconvert.preprocessors.ExtractOutputPreprocessor',
70 70 'IPython.nbconvert.preprocessors.CSSHTMLHeaderPreprocessor',
71 71 'IPython.nbconvert.preprocessors.RevealHelpPreprocessor',
72 72 'IPython.nbconvert.preprocessors.LatexPreprocessor',
73 'IPython.nbconvert.preprocessors.ClearOutputPreprocessor',
73 74 'IPython.nbconvert.preprocessors.HighlightMagicsPreprocessor'],
74 75 config=True,
75 76 help="""List of preprocessors available by default, by name, namespace,
76 77 instance, or type.""")
77 78
78 79
79 80 def __init__(self, config=None, **kw):
80 81 """
81 82 Public constructor
82 83
83 84 Parameters
84 85 ----------
85 86 config : config
86 87 User configuration instance.
87 88 """
88 89 with_default_config = self.default_config
89 90 if config:
90 91 with_default_config.merge(config)
91 92
92 93 super(Exporter, self).__init__(config=with_default_config, **kw)
93 94
94 95 self._init_preprocessors()
95 96
96 97
97 98 @property
98 99 def default_config(self):
99 100 return Config()
100 101
101 102 @nbformat.docstring_nbformat_mod
102 103 def from_notebook_node(self, nb, resources=None, **kw):
103 104 """
104 105 Convert a notebook from a notebook node instance.
105 106
106 107 Parameters
107 108 ----------
108 109 nb : :class:`~{nbformat_mod}.nbbase.NotebookNode`
109 110 Notebook node
110 111 resources : dict
111 112 Additional resources that can be accessed read/write by
112 113 preprocessors and filters.
113 114 **kw
114 115 Ignored (?)
115 116 """
116 117 nb_copy = copy.deepcopy(nb)
117 118 resources = self._init_resources(resources)
118 119
119 120 if 'language' in nb['metadata']:
120 121 resources['language'] = nb['metadata']['language'].lower()
121 122
122 123 # Preprocess
123 124 nb_copy, resources = self._preprocess(nb_copy, resources)
124 125
125 126 return nb_copy, resources
126 127
127 128
128 129 def from_filename(self, filename, resources=None, **kw):
129 130 """
130 131 Convert a notebook from a notebook file.
131 132
132 133 Parameters
133 134 ----------
134 135 filename : str
135 136 Full filename of the notebook file to open and convert.
136 137 """
137 138
138 139 # Pull the metadata from the filesystem.
139 140 if resources is None:
140 141 resources = ResourcesDict()
141 142 if not 'metadata' in resources or resources['metadata'] == '':
142 143 resources['metadata'] = ResourcesDict()
143 144 basename = os.path.basename(filename)
144 145 notebook_name = basename[:basename.rfind('.')]
145 146 resources['metadata']['name'] = notebook_name
146 147
147 148 modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(filename))
148 149 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
149 150
150 151 with io.open(filename, encoding='utf-8') as f:
151 152 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
152 153
153 154
154 155 def from_file(self, file_stream, resources=None, **kw):
155 156 """
156 157 Convert a notebook from a notebook file.
157 158
158 159 Parameters
159 160 ----------
160 161 file_stream : file-like object
161 162 Notebook file-like object to convert.
162 163 """
163 164 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
164 165
165 166
166 167 def register_preprocessor(self, preprocessor, enabled=False):
167 168 """
168 169 Register a preprocessor.
169 170 Preprocessors are classes that act upon the notebook before it is
170 171 passed into the Jinja templating engine. preprocessors are also
171 172 capable of passing additional information to the Jinja
172 173 templating engine.
173 174
174 175 Parameters
175 176 ----------
176 177 preprocessor : preprocessor
177 178 """
178 179 if preprocessor is None:
179 180 raise TypeError('preprocessor')
180 181 isclass = isinstance(preprocessor, type)
181 182 constructed = not isclass
182 183
183 184 # Handle preprocessor's registration based on it's type
184 185 if constructed and isinstance(preprocessor, py3compat.string_types):
185 186 # Preprocessor is a string, import the namespace and recursively call
186 187 # this register_preprocessor method
187 188 preprocessor_cls = import_item(preprocessor)
188 189 return self.register_preprocessor(preprocessor_cls, enabled)
189 190
190 191 if constructed and hasattr(preprocessor, '__call__'):
191 192 # Preprocessor is a function, no need to construct it.
192 193 # Register and return the preprocessor.
193 194 if enabled:
194 195 preprocessor.enabled = True
195 196 self._preprocessors.append(preprocessor)
196 197 return preprocessor
197 198
198 199 elif isclass and isinstance(preprocessor, MetaHasTraits):
199 200 # Preprocessor is configurable. Make sure to pass in new default for
200 201 # the enabled flag if one was specified.
201 202 self.register_preprocessor(preprocessor(parent=self), enabled)
202 203
203 204 elif isclass:
204 205 # Preprocessor is not configurable, construct it
205 206 self.register_preprocessor(preprocessor(), enabled)
206 207
207 208 else:
208 209 # Preprocessor is an instance of something without a __call__
209 210 # attribute.
210 211 raise TypeError('preprocessor')
211 212
212 213
213 214 def _init_preprocessors(self):
214 215 """
215 216 Register all of the preprocessors needed for this exporter, disabled
216 217 unless specified explicitly.
217 218 """
218 219 self._preprocessors = []
219 220
220 221 # Load default preprocessors (not necessarly enabled by default).
221 222 for preprocessor in self.default_preprocessors:
222 223 self.register_preprocessor(preprocessor)
223 224
224 225 # Load user-specified preprocessors. Enable by default.
225 226 for preprocessor in self.preprocessors:
226 227 self.register_preprocessor(preprocessor, enabled=True)
227 228
228 229
229 230 def _init_resources(self, resources):
230 231
231 232 #Make sure the resources dict is of ResourcesDict type.
232 233 if resources is None:
233 234 resources = ResourcesDict()
234 235 if not isinstance(resources, ResourcesDict):
235 236 new_resources = ResourcesDict()
236 237 new_resources.update(resources)
237 238 resources = new_resources
238 239
239 240 #Make sure the metadata extension exists in resources
240 241 if 'metadata' in resources:
241 242 if not isinstance(resources['metadata'], ResourcesDict):
242 243 resources['metadata'] = ResourcesDict(resources['metadata'])
243 244 else:
244 245 resources['metadata'] = ResourcesDict()
245 246 if not resources['metadata']['name']:
246 247 resources['metadata']['name'] = 'Notebook'
247 248
248 249 #Set the output extension
249 250 resources['output_extension'] = self.file_extension
250 251 return resources
251 252
252 253
253 254 def _preprocess(self, nb, resources):
254 255 """
255 256 Preprocess the notebook before passing it into the Jinja engine.
256 257 To preprocess the notebook is to apply all of the
257 258
258 259 Parameters
259 260 ----------
260 261 nb : notebook node
261 262 notebook that is being exported.
262 263 resources : a dict of additional resources that
263 264 can be accessed read/write by preprocessors
264 265 """
265 266
266 267 # Do a copy.deepcopy first,
267 268 # we are never safe enough with what the preprocessors could do.
268 269 nbc = copy.deepcopy(nb)
269 270 resc = copy.deepcopy(resources)
270 271
271 272 #Run each preprocessor on the notebook. Carry the output along
272 273 #to each preprocessor
273 274 for preprocessor in self._preprocessors:
274 275 nbc, resc = preprocessor(nbc, resc)
275 276 return nbc, resc
@@ -1,12 +1,13 b''
1 1 # Class base Preprocessors
2 2 from .base import Preprocessor
3 3 from .convertfigures import ConvertFiguresPreprocessor
4 4 from .svg2pdf import SVG2PDFPreprocessor
5 5 from .extractoutput import ExtractOutputPreprocessor
6 6 from .revealhelp import RevealHelpPreprocessor
7 7 from .latex import LatexPreprocessor
8 8 from .csshtmlheader import CSSHTMLHeaderPreprocessor
9 9 from .highlightmagics import HighlightMagicsPreprocessor
10 from .clearoutput import ClearOutputPreprocessor
10 11
11 12 # decorated function Preprocessors
12 13 from .coalescestreams import coalesce_streams
General Comments 0
You need to be logged in to leave comments. Login now