##// END OF EJS Templates
improve logging in nbconvert preprocessors...
MinRK -
Show More
@@ -1,111 +1,93 b''
1 """
1 """Base class for preprocessors"""
2 Module that re-groups preprocessor that would be applied to ipynb files
3 before going through the templating machinery.
4
2
5 It exposes a convenient class to inherit from to access configurability.
3 # Copyright (c) IPython Development Team.
6 """
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
5
19 from ..utils.base import NbConvertBase
6 from ..utils.base import NbConvertBase
20 from IPython.utils.traitlets import Bool
7 from IPython.utils.traitlets import Bool
21
8
22 #-----------------------------------------------------------------------------
23 # Classes and Functions
24 #-----------------------------------------------------------------------------
25
9
26 class Preprocessor(NbConvertBase):
10 class Preprocessor(NbConvertBase):
27 """ A configurable preprocessor
11 """ A configurable preprocessor
28
12
29 Inherit from this class if you wish to have configurability for your
13 Inherit from this class if you wish to have configurability for your
30 preprocessor.
14 preprocessor.
31
15
32 Any configurable traitlets this class exposed will be configurable in
16 Any configurable traitlets this class exposed will be configurable in
33 profiles using c.SubClassName.atribute=value
17 profiles using c.SubClassName.attribute = value
34
18
35 you can overwrite :meth:`preprocess_cell` to apply a transformation
19 you can overwrite :meth:`preprocess_cell` to apply a transformation
36 independently on each cell or :meth:`preprocess` if you prefer your own
20 independently on each cell or :meth:`preprocess` if you prefer your own
37 logic. See corresponding docstring for informations.
21 logic. See corresponding docstring for informations.
38
22
39 Disabled by default and can be enabled via the config by
23 Disabled by default and can be enabled via the config by
40 'c.YourPreprocessorName.enabled = True'
24 'c.YourPreprocessorName.enabled = True'
41 """
25 """
42
26
43 enabled = Bool(False, config=True)
27 enabled = Bool(False, config=True)
44
28
45 def __init__(self, **kw):
29 def __init__(self, **kw):
46 """
30 """
47 Public constructor
31 Public constructor
48
32
49 Parameters
33 Parameters
50 ----------
34 ----------
51 config : Config
35 config : Config
52 Configuration file structure
36 Configuration file structure
53 **kw : misc
37 **kw : misc
54 Additional arguments
38 Additional arguments
55 """
39 """
56
40
57 super(Preprocessor, self).__init__(**kw)
41 super(Preprocessor, self).__init__(**kw)
58
42
59
43
60 def __call__(self, nb, resources):
44 def __call__(self, nb, resources):
61 if self.enabled:
45 if self.enabled:
46 self.log.debug("Applying preprocessor: %s", self.__class__.__name__)
62 return self.preprocess(nb,resources)
47 return self.preprocess(nb,resources)
63 else:
48 else:
64 return nb, resources
49 return nb, resources
65
50
66
51
67 def preprocess(self, nb, resources):
52 def preprocess(self, nb, resources):
68 """
53 """
69 Preprocessing to apply on each notebook.
54 Preprocessing to apply on each notebook.
70
55
71 You should return modified nb, resources.
56 Must return modified nb, resources.
57
72 If you wish to apply your preprocessing to each cell, you might want
58 If you wish to apply your preprocessing to each cell, you might want
73 to overwrite preprocess_cell method instead.
59 to override preprocess_cell method instead.
74
60
75 Parameters
61 Parameters
76 ----------
62 ----------
77 nb : NotebookNode
63 nb : NotebookNode
78 Notebook being converted
64 Notebook being converted
79 resources : dictionary
65 resources : dictionary
80 Additional resources used in the conversion process. Allows
66 Additional resources used in the conversion process. Allows
81 preprocessors to pass variables into the Jinja engine.
67 preprocessors to pass variables into the Jinja engine.
82 """
68 """
83 self.log.debug("Applying preprocess: %s", self.__class__.__name__)
84 try :
85 for worksheet in nb.worksheets:
69 for worksheet in nb.worksheets:
86 for index, cell in enumerate(worksheet.cells):
70 for index, cell in enumerate(worksheet.cells):
87 worksheet.cells[index], resources = self.preprocess_cell(cell, resources, index)
71 worksheet.cells[index], resources = self.preprocess_cell(cell, resources, index)
88 return nb, resources
72 return nb, resources
89 except NotImplementedError:
90 raise NotImplementedError('should be implemented by subclass')
91
73
92
74
93 def preprocess_cell(self, cell, resources, index):
75 def preprocess_cell(self, cell, resources, index):
94 """
76 """
95 Overwrite if you want to apply some preprocessing to each cell. You
77 Override if you want to apply some preprocessing to each cell.
96 should return modified cell and resource dictionary.
78 Must return modified cell and resource dictionary.
97
79
98 Parameters
80 Parameters
99 ----------
81 ----------
100 cell : NotebookNode cell
82 cell : NotebookNode cell
101 Notebook cell being processed
83 Notebook cell being processed
102 resources : dictionary
84 resources : dictionary
103 Additional resources used in the conversion process. Allows
85 Additional resources used in the conversion process. Allows
104 preprocessors to pass variables into the Jinja engine.
86 preprocessors to pass variables into the Jinja engine.
105 index : int
87 index : int
106 Index of the cell being processed
88 Index of the cell being processed
107 """
89 """
108
90
109 raise NotImplementedError('should be implemented by subclass')
91 raise NotImplementedError('should be implemented by subclass')
110 return cell, resources
92 return cell, resources
111
93
@@ -1,85 +1,77 b''
1 """Module that allows latex output notebooks to be conditioned before
1 """Preprocessor for merging consecutive stream outputs for easier handling."""
2 they are converted. Exposes a decorator (@cell_preprocessor) in
2
3 addition to the coalesce_streams pre-proccessor.
3 # Copyright (c) IPython Development Team.
4 """
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # 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
5
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16 import re
6 import re
17
7
18 #-----------------------------------------------------------------------------
19 # Functions
20 #-----------------------------------------------------------------------------
21 def cell_preprocessor(function):
8 def cell_preprocessor(function):
22 """
9 """
23 Wrap a function to be executed on all cells of a notebook
10 Wrap a function to be executed on all cells of a notebook
24
11
25 The wrapped function should have these parameters:
12 The wrapped function should have these parameters:
26
13
27 cell : NotebookNode cell
14 cell : NotebookNode cell
28 Notebook cell being processed
15 Notebook cell being processed
29 resources : dictionary
16 resources : dictionary
30 Additional resources used in the conversion process. Allows
17 Additional resources used in the conversion process. Allows
31 preprocessors to pass variables into the Jinja engine.
18 preprocessors to pass variables into the Jinja engine.
32 index : int
19 index : int
33 Index of the cell being processed
20 Index of the cell being processed
34 """
21 """
35
22
36 def wrappedfunc(nb, resources):
23 def wrappedfunc(nb, resources):
24 from IPython.config import Application
25 if Application.initialized():
26 Application.instance().log.debug(
27 "Applying preprocessor: %s", function.__name__
28 )
37 for worksheet in nb.worksheets :
29 for worksheet in nb.worksheets:
38 for index, cell in enumerate(worksheet.cells):
30 for index, cell in enumerate(worksheet.cells):
39 worksheet.cells[index], resources = function(cell, resources, index)
31 worksheet.cells[index], resources = function(cell, resources, index)
40 return nb, resources
32 return nb, resources
41 return wrappedfunc
33 return wrappedfunc
42
34
43 cr_pat = re.compile(r'.*\r(?=[^\n])')
35 cr_pat = re.compile(r'.*\r(?=[^\n])')
44
36
45 @cell_preprocessor
37 @cell_preprocessor
46 def coalesce_streams(cell, resources, index):
38 def coalesce_streams(cell, resources, index):
47 """
39 """
48 Merge consecutive sequences of stream output into single stream
40 Merge consecutive sequences of stream output into single stream
49 to prevent extra newlines inserted at flush calls
41 to prevent extra newlines inserted at flush calls
50
42
51 Parameters
43 Parameters
52 ----------
44 ----------
53 cell : NotebookNode cell
45 cell : NotebookNode cell
54 Notebook cell being processed
46 Notebook cell being processed
55 resources : dictionary
47 resources : dictionary
56 Additional resources used in the conversion process. Allows
48 Additional resources used in the conversion process. Allows
57 transformers to pass variables into the Jinja engine.
49 transformers to pass variables into the Jinja engine.
58 index : int
50 index : int
59 Index of the cell being processed
51 Index of the cell being processed
60 """
52 """
61
53
62 outputs = cell.get('outputs', [])
54 outputs = cell.get('outputs', [])
63 if not outputs:
55 if not outputs:
64 return cell, resources
56 return cell, resources
65
57
66 last = outputs[0]
58 last = outputs[0]
67 new_outputs = [last]
59 new_outputs = [last]
68 for output in outputs[1:]:
60 for output in outputs[1:]:
69 if (output.output_type == 'stream' and
61 if (output.output_type == 'stream' and
70 last.output_type == 'stream' and
62 last.output_type == 'stream' and
71 last.stream == output.stream
63 last.stream == output.stream
72 ):
64 ):
73 last.text += output.text
65 last.text += output.text
74
66
75 else:
67 else:
76 new_outputs.append(output)
68 new_outputs.append(output)
77 last = output
69 last = output
78
70
79 # process \r characters
71 # process \r characters
80 for output in new_outputs:
72 for output in new_outputs:
81 if output.output_type == 'stream':
73 if output.output_type == 'stream':
82 output.text = cr_pat.sub('', output.text)
74 output.text = cr_pat.sub('', output.text)
83
75
84 cell.outputs = new_outputs
76 cell.outputs = new_outputs
85 return cell, resources
77 return cell, resources
General Comments 0
You need to be logged in to leave comments. Login now