Show More
@@ -0,0 +1,23 b'' | |||||
|
1 | """Latex transformer. | |||
|
2 | ||||
|
3 | Module that allows latex output notebooks to be conditioned before | |||
|
4 | they are converted. | |||
|
5 | """ | |||
|
6 | #----------------------------------------------------------------------------- | |||
|
7 | # Copyright (c) 2013, the IPython Development Team. | |||
|
8 | # | |||
|
9 | # Distributed under the terms of the Modified BSD License. | |||
|
10 | # | |||
|
11 | # The full license is in the file COPYING.txt, distributed with this software. | |||
|
12 | #----------------------------------------------------------------------------- | |||
|
13 | ||||
|
14 | #----------------------------------------------------------------------------- | |||
|
15 | # Functions | |||
|
16 | #----------------------------------------------------------------------------- | |||
|
17 | def export_sphinx_report(nb, config=None): | |||
|
18 | pass | |||
|
19 | def export_sphinx_report(nb, fileName, config=None): | |||
|
20 | pass | |||
|
21 | ||||
|
22 | #TODO: Add basic export/import utility functions. | |||
|
23 | __author__ = 'root' |
@@ -0,0 +1,82 b'' | |||||
|
1 | # ANSI color functions: | |||
|
2 | import re | |||
|
3 | def remove_ansi(src): | |||
|
4 | """Strip all ANSI color escape sequences from input string. | |||
|
5 | ||||
|
6 | Parameters | |||
|
7 | ---------- | |||
|
8 | src : string | |||
|
9 | ||||
|
10 | Returns | |||
|
11 | ------- | |||
|
12 | string | |||
|
13 | """ | |||
|
14 | return re.sub(r'\033\[(0|\d;\d\d)m', '', src) | |||
|
15 | ||||
|
16 | ||||
|
17 | def ansi2html(txt): | |||
|
18 | """Render ANSI colors as HTML colors | |||
|
19 | ||||
|
20 | This is equivalent to util.fixConsole in utils.js | |||
|
21 | ||||
|
22 | Parameters | |||
|
23 | ---------- | |||
|
24 | txt : string | |||
|
25 | ||||
|
26 | Returns | |||
|
27 | ------- | |||
|
28 | string | |||
|
29 | """ | |||
|
30 | ||||
|
31 | ansi_colormap = { | |||
|
32 | '30': 'ansiblack', | |||
|
33 | '31': 'ansired', | |||
|
34 | '32': 'ansigreen', | |||
|
35 | '33': 'ansiyellow', | |||
|
36 | '34': 'ansiblue', | |||
|
37 | '35': 'ansipurple', | |||
|
38 | '36': 'ansicyan', | |||
|
39 | '37': 'ansigrey', | |||
|
40 | '01': 'ansibold', | |||
|
41 | } | |||
|
42 | ||||
|
43 | # do ampersand first | |||
|
44 | txt = txt.replace('&', '&') | |||
|
45 | html_escapes = { | |||
|
46 | '<': '<', | |||
|
47 | '>': '>', | |||
|
48 | "'": ''', | |||
|
49 | '"': '"', | |||
|
50 | '`': '`', | |||
|
51 | } | |||
|
52 | for c, escape in html_escapes.iteritems(): | |||
|
53 | txt = txt.replace(c, escape) | |||
|
54 | ||||
|
55 | ansi_re = re.compile('\x1b' + r'\[([\dA-Fa-f;]*?)m') | |||
|
56 | m = ansi_re.search(txt) | |||
|
57 | opened = False | |||
|
58 | cmds = [] | |||
|
59 | opener = '' | |||
|
60 | closer = '' | |||
|
61 | while m: | |||
|
62 | cmds = m.groups()[0].split(';') | |||
|
63 | closer = '</span>' if opened else '' | |||
|
64 | # True if there is there more than one element in cmds, *or* | |||
|
65 | # if there is only one but it is not equal to a string of zeroes. | |||
|
66 | opened = len(cmds) > 1 or cmds[0] != '0' * len(cmds[0]) | |||
|
67 | classes = [] | |||
|
68 | for cmd in cmds: | |||
|
69 | if cmd in ansi_colormap: | |||
|
70 | classes.append(ansi_colormap.get(cmd)) | |||
|
71 | ||||
|
72 | if classes: | |||
|
73 | opener = '<span class="%s">' % (' '.join(classes)) | |||
|
74 | else: | |||
|
75 | opener = '' | |||
|
76 | txt = re.sub(ansi_re, closer + opener, txt, 1) | |||
|
77 | ||||
|
78 | m = ansi_re.search(txt) | |||
|
79 | ||||
|
80 | if opened: | |||
|
81 | txt += '</span>' | |||
|
82 | return txt |
@@ -0,0 +1,39 b'' | |||||
|
1 | # Our own imports | |||
|
2 | from utils.lexers import IPythonLexer | |||
|
3 | ||||
|
4 | #----------------------------------------------------------------------------- | |||
|
5 | # Globals and constants | |||
|
6 | #----------------------------------------------------------------------------- | |||
|
7 | _multiline_outputs = ['text', 'html', 'svg', 'latex', 'javascript', 'json'] | |||
|
8 | ||||
|
9 | ||||
|
10 | #----------------------------------------------------------------------------- | |||
|
11 | # Utility functions | |||
|
12 | #----------------------------------------------------------------------------- | |||
|
13 | def highlight(src, lang='ipython'): | |||
|
14 | """ | |||
|
15 | Return a syntax-highlighted version of the input source as html output. | |||
|
16 | """ | |||
|
17 | from pygments.formatters import HtmlFormatter | |||
|
18 | return pygment_highlight(src, HtmlFormatter(), lang) | |||
|
19 | ||||
|
20 | def highlight2latex(src, lang='ipython'): | |||
|
21 | """ | |||
|
22 | Return a syntax-highlighted version of the input source as latex output. | |||
|
23 | """ | |||
|
24 | from pygments.formatters import LatexFormatter | |||
|
25 | return pygment_highlight(src, LatexFormatter(), lang) | |||
|
26 | ||||
|
27 | def pygment_highlight(src, output_formatter, lang='ipython'): | |||
|
28 | """ | |||
|
29 | Return a syntax-highlighted version of the input source | |||
|
30 | """ | |||
|
31 | from pygments import highlight | |||
|
32 | from pygments.lexers import get_lexer_by_name | |||
|
33 | ||||
|
34 | if lang == 'ipython': | |||
|
35 | lexer = IPythonLexer() | |||
|
36 | else: | |||
|
37 | lexer = get_lexer_by_name(lang, stripall=True) | |||
|
38 | ||||
|
39 | return highlight(src, lexer, output_formatter) |
@@ -0,0 +1,43 b'' | |||||
|
1 | ||||
|
2 | def cell_preprocessor(function): | |||
|
3 | """ wrap a function to be executed on all cells of a notebook | |||
|
4 | ||||
|
5 | wrapped function parameters : | |||
|
6 | cell : the cell | |||
|
7 | other : external resources | |||
|
8 | index : index of the cell | |||
|
9 | """ | |||
|
10 | def wrappedfunc(nb, other): | |||
|
11 | for worksheet in nb.worksheets : | |||
|
12 | for index, cell in enumerate(worksheet.cells): | |||
|
13 | worksheet.cells[index], other = function(cell, other, index) | |||
|
14 | return nb, other | |||
|
15 | return wrappedfunc | |||
|
16 | ||||
|
17 | ||||
|
18 | @cell_preprocessor | |||
|
19 | def coalesce_streams(cell, other, count): | |||
|
20 | """merge consecutive sequences of stream output into single stream | |||
|
21 | ||||
|
22 | to prevent extra newlines inserted at flush calls | |||
|
23 | ||||
|
24 | TODO: handle \r deletion | |||
|
25 | """ | |||
|
26 | outputs = cell.get('outputs', []) | |||
|
27 | if not outputs: | |||
|
28 | return cell, other | |||
|
29 | new_outputs = [] | |||
|
30 | last = outputs[0] | |||
|
31 | new_outputs = [last] | |||
|
32 | for output in outputs[1:]: | |||
|
33 | if (output.output_type == 'stream' and | |||
|
34 | last.output_type == 'stream' and | |||
|
35 | last.stream == output.stream | |||
|
36 | ): | |||
|
37 | last.text += output.text | |||
|
38 | else: | |||
|
39 | new_outputs.append(output) | |||
|
40 | ||||
|
41 | cell.outputs = new_outputs | |||
|
42 | return cell, other | |||
|
43 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
@@ -1,333 +1,266 b'' | |||||
1 | """Exporter for the notebook conversion pipeline. |
|
1 | """Exporter for the notebook conversion pipeline. | |
2 |
|
2 | |||
3 | This module defines Exporter, a highly configurable converter |
|
3 | This module defines Exporter, a highly configurable converter | |
4 | that uses Jinja2 to export notebook files into different format. |
|
4 | that uses Jinja2 to export notebook files into different format. | |
5 |
|
5 | |||
6 | You can register both pre-transformers that will act on the notebook format |
|
6 | You can register both pre-transformers that will act on the notebook format | |
7 | befor conversion and jinja filter that would then be availlable in the templates |
|
7 | befor conversion and jinja filter that would then be availlable in the templates | |
8 | """ |
|
8 | """ | |
9 |
|
9 | |||
10 | #----------------------------------------------------------------------------- |
|
10 | #----------------------------------------------------------------------------- | |
11 | # Copyright (c) 2013, the IPython Development Team. |
|
11 | # Copyright (c) 2013, the IPython Development Team. | |
12 | # |
|
12 | # | |
13 | # Distributed under the terms of the Modified BSD License. |
|
13 | # Distributed under the terms of the Modified BSD License. | |
14 | # |
|
14 | # | |
15 | # The full license is in the file COPYING.txt, distributed with this software. |
|
15 | # The full license is in the file COPYING.txt, distributed with this software. | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 |
|
17 | |||
18 | #----------------------------------------------------------------------------- |
|
18 | #----------------------------------------------------------------------------- | |
19 | # Imports |
|
19 | # Imports | |
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 | from __future__ import print_function, absolute_import |
|
21 | from __future__ import print_function, absolute_import | |
22 |
|
22 | |||
23 | # Stdlib imports |
|
23 | # Stdlib imports | |
24 | import io |
|
24 | import io | |
25 | import os |
|
25 | import os | |
26 | import re |
|
|||
27 |
|
26 | |||
28 | # IPython imports |
|
27 | # IPython imports | |
29 | from IPython.config.configurable import Configurable |
|
28 | from IPython.config.configurable import Configurable | |
30 | from IPython.nbformat import current as nbformat |
|
29 | from IPython.nbformat import current as nbformat | |
31 | from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Bool |
|
30 | from IPython.utils.traitlets import MetaHasTraits, Unicode, List, Bool | |
32 | from IPython.utils.text import indent |
|
31 | from IPython.utils.text import indent | |
33 |
|
32 | |||
34 | # other libs/dependencies |
|
33 | # other libs/dependencies | |
35 | from jinja2 import Environment, FileSystemLoader |
|
34 | from jinja2 import Environment, FileSystemLoader | |
36 | from markdown import markdown |
|
35 | from markdown import markdown | |
37 |
|
36 | |||
38 | # local import (pre-transformers) |
|
37 | # local import | |
39 | from exceptions import ConversionException |
|
38 | import filters.strings | |
40 | from . import transformers as trans #TODO |
|
39 | import filters.markdown | |
41 | from .utils import get_lines #TODO |
|
40 | import filters.latex | |
42 | from .utils import remove_ansi #TODO |
|
41 | import filters.datatypefilter | |
43 | from .utils import highlight, ansi2html #TODO |
|
42 | import filters.pygments | |
|
43 | import filters.ansi | |||
|
44 | ||||
|
45 | import transformers.extractfigure | |||
|
46 | import transformers.csshtmlheader | |||
|
47 | import transformers.revealhelp | |||
|
48 | import transformers.coalescestreams | |||
44 |
|
49 | |||
45 | import .utils.strings as strings |
|
|||
46 | import .utils.markdown as markdown_utils |
|
|||
47 | import .utils.datatypefilter.DataTypeFilter as DataTypeFilter |
|
|||
48 |
|
50 | |||
49 | #----------------------------------------------------------------------------- |
|
51 | #----------------------------------------------------------------------------- | |
50 | # Globals and constants |
|
52 | # Globals and constants | |
51 | #----------------------------------------------------------------------------- |
|
53 | #----------------------------------------------------------------------------- | |
52 |
|
54 | |||
53 | #Standard Jinja2 environment constants |
|
55 | #Standard Jinja2 environment constants | |
54 | TEMPLATE_PATH = "/../templates/" |
|
56 | TEMPLATE_PATH = "/../templates/" | |
55 | TEMPLATE_SKELETON_PATH = "/../templates/skeleton/" |
|
57 | TEMPLATE_SKELETON_PATH = "/../templates/skeleton/" | |
56 | TEMPLATE_EXTENSION = ".tpl" |
|
58 | TEMPLATE_EXTENSION = ".tpl" | |
57 |
|
59 | |||
58 | #Jinja2 extensions to load. |
|
60 | #Jinja2 extensions to load. | |
59 | JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols'] |
|
61 | JINJA_EXTENSIONS = ['jinja2.ext.loopcontrols'] | |
60 |
|
62 | |||
61 | #----------------------------------------------------------------------------- |
|
63 | #----------------------------------------------------------------------------- | |
62 | # Classes and functions |
|
64 | # Classes and functions | |
63 | #----------------------------------------------------------------------------- |
|
65 | #----------------------------------------------------------------------------- | |
64 | class Exporter(Configurable): |
|
66 | class Exporter(Configurable): | |
65 | """ A Jinja2 base converter templates |
|
67 | """ A Jinja2 base converter templates | |
66 |
|
68 | |||
67 |
Preprocess the |
|
69 | Pre-process the IPYNB files, feed it through Jinja2 templates, | |
68 | and spit an converted files and a data object with other data |
|
70 | and spit an converted files and a data object with other data | |
69 | should be mostly configurable |
|
71 | should be mostly configurable | |
70 | """ |
|
72 | """ | |
71 |
|
73 | |||
72 | pre_transformer_order = List(['haspyout_transformer'], |
|
74 | pre_transformer_order = List(['haspyout_transformer'], | |
73 | config=True, |
|
75 | config=True, | |
74 | help= """ |
|
76 | help= """ | |
75 |
An ordered list of pre |
|
77 | An ordered list of pre-transformer to apply to the IPYNB | |
76 | file before running through templates |
|
78 | file before running through templates | |
77 | """ |
|
79 | """ | |
78 | ) |
|
80 | ) | |
79 |
|
81 | |||
80 | #TODO: Flagged for removal. |
|
|||
81 | tex_environement = Bool( |
|
|||
82 | False, |
|
|||
83 | config=True, |
|
|||
84 | help=" Whether or not the user is exporting to latex.") |
|
|||
85 |
|
||||
86 | template_file = Unicode( |
|
82 | template_file = Unicode( | |
87 | '', config=True, |
|
83 | '', config=True, | |
88 | help="Name of the template file to use") |
|
84 | help="Name of the template file to use") | |
89 |
|
85 | |||
90 | fileext = Unicode( |
|
86 | fileext = Unicode( | |
91 | 'txt', config=True, |
|
87 | 'txt', config=True, | |
92 | help="Extension of the file that should be written to disk" |
|
88 | help="Extension of the file that should be written to disk" | |
93 | ) |
|
89 | ) | |
94 |
|
90 | |||
95 | stdout = Bool( |
|
91 | stdout = Bool( | |
96 | True, config=True, |
|
92 | True, config=True, | |
97 |
help="""Whether to print the converted |
|
93 | help="""Whether to print the converted IPYNB file to stdout | |
98 | "use full do diff files without actually writing a new file""" |
|
94 | "use full do diff files without actually writing a new file""" | |
99 | ) |
|
95 | ) | |
100 |
|
96 | |||
101 | write = Bool( |
|
97 | write = Bool( | |
102 | False, config=True, |
|
98 | False, config=True, | |
103 | help="""Should the converted notebook file be written to disk |
|
99 | help="""Should the converted notebook file be written to disk | |
104 | along with potential extracted resources.""" |
|
100 | along with potential extracted resources.""" | |
105 | ) |
|
101 | ) | |
106 |
|
102 | |||
107 | #Processors that process the input data prior to the export, set in the |
|
103 | #Processors that process the input data prior to the export, set in the | |
108 | #constructor for this class. |
|
104 | #constructor for this class. | |
109 | preprocessors = [] |
|
105 | preprocessors = [] | |
110 |
|
106 | |||
111 | def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw): |
|
107 | def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw): | |
112 | """ Init a new converter. |
|
108 | """ Init a new converter. | |
113 |
|
109 | |||
114 | config: the Configurable config object to pass around. |
|
110 | config: the Configurable config object to pass around. | |
115 |
|
111 | |||
116 | preprocessors: dict of **availlable** key/value function to run on |
|
112 | preprocessors: dict of **availlable** key/value function to run on | |
117 | ipynb json data before conversion to extract/inline file. |
|
113 | ipynb json data before conversion to extract/inline file. | |
118 | See `transformer.py` and `ConfigurableTransformers` |
|
114 | See `transformer.py` and `ConfigurableTransformers` | |
119 |
|
115 | |||
120 | set the order in which the transformers should apply |
|
116 | set the order in which the transformers should apply | |
121 | with the `pre_transformer_order` trait of this class |
|
117 | with the `pre_transformer_order` trait of this class | |
122 |
|
118 | |||
123 | transformers registerd by this key will take precedence on |
|
119 | transformers registerd by this key will take precedence on | |
124 | default one. |
|
120 | default one. | |
125 |
|
121 | |||
126 | jinja_filters: dict of supplementary jinja filter that should be made |
|
122 | jinja_filters: dict of supplementary jinja filter that should be made | |
127 | availlable in template. If those are of Configurable Class type, |
|
123 | availlable in template. If those are of Configurable Class type, | |
128 | they will be instanciated with the config object as argument. |
|
124 | they will be instanciated with the config object as argument. | |
129 |
|
125 | |||
130 | user defined filter will overwrite the one availlable by default. |
|
126 | user defined filter will overwrite the one availlable by default. | |
131 | """ |
|
127 | """ | |
132 |
|
128 | |||
133 | #Merge default config options with user specific override options. |
|
129 | #Set the default options for the exporter. | |
134 |
default_config = self. |
|
130 | default_config = self.config | |
|
131 | ||||
|
132 | #Set properties that must be set in the config class in order to | |||
|
133 | #propagate to other classes. | |||
|
134 | default_config.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text'] | |||
|
135 | default_config.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text'] | |||
|
136 | ||||
|
137 | #Set default properties of the exporter. | |||
|
138 | #For most (or all cases), the template file name matches the format name. | |||
|
139 | self.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text'] | |||
|
140 | self.template_file = export_format | |||
|
141 | ||||
135 | if not config == None: |
|
142 | if not config == None: | |
136 | default_config._merge(config) |
|
143 | default_config._merge(config) | |
137 | config = default_config |
|
144 | config = default_config | |
138 |
|
145 | |||
139 | #Call the base class constructor |
|
146 | #Call the base class constructor | |
140 | super(Exporter, self).__init__(config=config, **kw) |
|
147 | super(Exporter, self).__init__(config=config, **kw) | |
141 |
|
148 | |||
142 | #Standard environment |
|
149 | #Standard environment | |
143 | self.ext = TEMPLATE_EXTENSION |
|
150 | self.ext = TEMPLATE_EXTENSION | |
144 |
self. |
|
151 | self._init_environment() | |
145 | loader=FileSystemLoader([ |
|
|||
146 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH, |
|
|||
147 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH, |
|
|||
148 | ]), |
|
|||
149 | extensions=JINJA_EXTENSIONS |
|
|||
150 | ) |
|
|||
151 |
|
152 | |||
152 | for name in self.pre_transformer_order: |
|
153 | #TODO: Implement reflection style methods to get user transformers. | |
153 | # get the user-defined transformer first |
|
154 | #for name in self.pre_transformer_order: | |
154 | transformer = preprocessors.get(name, getattr(trans, name, None)) |
|
155 | # # get the user-defined transformer first | |
155 | if isinstance(transformer, MetaHasTraits): |
|
156 | # transformer = preprocessors.get(name, getattr(trans, name, None)) | |
156 | transformer = transformer(config=config) |
|
157 | # if isinstance(transformer, MetaHasTraits): | |
157 | self.preprocessors.append(transformer) |
|
158 | # transformer = transformer(config=config) | |
|
159 | # self.preprocessors.append(transformer) | |||
158 |
|
160 | |||
159 | #For compatibility, TODO: remove later. |
|
161 | #For compatibility, TODO: remove later. | |
160 | self.preprocessors.append(trans.coalesce_streams) |
|
162 | self.preprocessors.append(transformers.coalescestreams.coalesce_streams) | |
161 | self.preprocessors.append(trans.ExtractFigureTransformer(config=config)) |
|
163 | self.preprocessors.append(transformers.extractfigure.ExtractFigureTransformer(config=config)) | |
162 | self.preprocessors.append(trans.RevealHelpTransformer(config=config)) |
|
164 | self.preprocessors.append(transformers.revealhelp.RevealHelpTransformer(config=config)) | |
163 | self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config)) |
|
165 | self.preprocessors.append(transformers.csshtmlheader.CSSHtmlHeaderTransformer(config=config)) | |
164 | self.preprocessors.append(LatexTransformer(config=config)) |
|
|||
165 |
|
||||
166 | #Only load the sphinx transformer if the file reference worked |
|
|||
167 | #(Sphinx dependencies exist on the user's machine.) |
|
|||
168 | if SphinxTransformer: |
|
|||
169 | self.preprocessors.append(SphinxTransformer(config=config)) |
|
|||
170 |
|
166 | |||
171 | #Add filters to the Jinja2 environment |
|
167 | #Add filters to the Jinja2 environment | |
172 | self.env.filters['filter_data_type'] = DataTypeFilter(config=config) |
|
168 | self._register_filters(config) | |
173 | self.env.filters['pycomment'] = _python_comment |
|
|||
174 | self.env.filters['indent'] = indent |
|
|||
175 | self.env.filters['rm_fake'] = _rm_fake |
|
|||
176 | self.env.filters['rm_ansi'] = remove_ansi |
|
|||
177 | self.env.filters['markdown'] = markdown |
|
|||
178 | self.env.filters['ansi2html'] = ansi2html |
|
|||
179 | self.env.filters['markdown2latex'] = markdown_utils.markdown2latex |
|
|||
180 | self.env.filters['markdown2rst'] = markdown_utils.markdown2rst |
|
|||
181 | self.env.filters['get_lines'] = get_lines |
|
|||
182 | self.env.filters['wrap'] = strings.wrap |
|
|||
183 | self.env.filters['rm_dollars'] = strings.strip_dollars |
|
|||
184 | self.env.filters['rm_math_space'] = rm_math_space |
|
|||
185 | self.env.filters['highlight2html'] = highlight |
|
|||
186 | self.env.filters['highlight2latex'] = highlight2latex |
|
|||
187 |
|
||||
188 | #Latex specific filters |
|
|||
189 | if self.tex_environement: |
|
|||
190 | self.env.filters['escape_tex'] = _escape_tex |
|
|||
191 | self.env.filters['highlight'] = highlight2latex |
|
|||
192 | else: |
|
|||
193 | self.env.filters['highlight'] = highlight |
|
|||
194 |
|
169 | |||
195 | #Load user filters. Overwrite existing filters if need be. |
|
170 | #Load user filters. Overwrite existing filters if need be. | |
196 | for key, user_filter in jinja_filters.iteritems(): |
|
171 | for key, user_filter in jinja_filters.iteritems(): | |
197 | if isinstance(user_filter, MetaHasTraits): |
|
172 | if isinstance(user_filter, MetaHasTraits): | |
198 | self.env.filters[key] = user_filter(config=config) |
|
173 | self.env.filters[key] = user_filter(config=config) | |
199 | else: |
|
174 | else: | |
200 | self.env.filters[key] = user_filter |
|
175 | self.env.filters[key] = user_filter | |
201 |
|
176 | |||
202 | #Load the template file. |
|
177 | #Load the template file. | |
203 | self.template = self.env.get_template(self.template_file+self.ext) |
|
178 | self.template = self.env.get_template(self.template_file+self.ext) | |
204 |
|
179 | |||
205 |
|
180 | |||
206 | def export(self, nb): |
|
181 | def export(self, nb): | |
207 | """Export notebook object |
|
182 | """Export notebook object | |
208 |
|
183 | |||
209 | nb: Notebook object to export. |
|
184 | nb: Notebook object to export. | |
210 |
|
185 | |||
211 | Returns both the converted ipynb file and a dict containing the |
|
186 | Returns both the converted ipynb file and a dict containing the | |
212 | resources created along the way via the transformers and Jinja2 |
|
187 | resources created along the way via the transformers and Jinja2 | |
213 | processing. |
|
188 | processing. | |
214 | """ |
|
189 | """ | |
215 |
|
190 | |||
216 | nb, resources = self._preprocess(nb) |
|
191 | nb, resources = self._preprocess(nb) | |
217 | return self.template.render(nb=nb, resources=resources), resources |
|
192 | return self.template.render(nb=nb, resources=resources), resources | |
218 |
|
193 | |||
219 |
|
194 | |||
220 | def from_filename(self, filename): |
|
195 | def from_filename(self, filename): | |
221 | """Read and export a notebook from a filename |
|
196 | """Read and export a notebook from a filename | |
222 |
|
197 | |||
223 | filename: Filename of the notebook file to export. |
|
198 | filename: Filename of the notebook file to export. | |
224 |
|
199 | |||
225 | Returns both the converted ipynb file and a dict containing the |
|
200 | Returns both the converted ipynb file and a dict containing the | |
226 | resources created along the way via the transformers and Jinja2 |
|
201 | resources created along the way via the transformers and Jinja2 | |
227 | processing. |
|
202 | processing. | |
228 | """ |
|
203 | """ | |
229 | with io.open(filename) as f: |
|
204 | with io.open(filename) as f: | |
230 | return self.export(nbformat.read(f, 'json')) |
|
205 | return self.export(nbformat.read(f, 'json')) | |
231 |
|
206 | |||
232 |
|
207 | |||
233 | def from_file(self, file_stream): |
|
208 | def from_file(self, file_stream): | |
234 | """Read and export a notebook from a filename |
|
209 | """Read and export a notebook from a filename | |
235 |
|
210 | |||
236 | file_stream: File handle of file that contains notebook data. |
|
211 | file_stream: File handle of file that contains notebook data. | |
237 |
|
212 | |||
238 | Returns both the converted ipynb file and a dict containing the |
|
213 | Returns both the converted ipynb file and a dict containing the | |
239 | resources created along the way via the transformers and Jinja2 |
|
214 | resources created along the way via the transformers and Jinja2 | |
240 | processing. |
|
215 | processing. | |
241 | """ |
|
216 | """ | |
242 |
|
217 | |||
243 | return self.export(nbformat.read(file_stream, 'json')) |
|
218 | return self.export(nbformat.read(file_stream, 'json')) | |
244 |
|
219 | |||
245 |
|
220 | |||
|
221 | def _init_environment(self): | |||
|
222 | self.env = Environment( | |||
|
223 | loader=FileSystemLoader([ | |||
|
224 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH, | |||
|
225 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH, | |||
|
226 | ]), | |||
|
227 | extensions=JINJA_EXTENSIONS | |||
|
228 | ) | |||
|
229 | ||||
|
230 | ||||
|
231 | def _register_filters(self, config): | |||
|
232 | self.env.filters['indent'] = indent | |||
|
233 | self.env.filters['markdown'] = markdown | |||
|
234 | ||||
|
235 | self.env.filters['ansi2html'] = filters.ansi.ansi2html | |||
|
236 | self.env.filters['filter_data_type'] = filters.datatypefilter.DataTypeFilter(config=config) | |||
|
237 | self.env.filters['get_lines'] = filters.strings.get_lines | |||
|
238 | self.env.filters['highlight'] = filters.pygments.highlight | |||
|
239 | self.env.filters['highlight2html'] = filters.pygments.highlight | |||
|
240 | self.env.filters['highlight2latex'] = filters.pygments.highlight2latex | |||
|
241 | self.env.filters['markdown2latex'] = filters.markdown.markdown2latex | |||
|
242 | self.env.filters['markdown2rst'] = filters.markdown.markdown2rst | |||
|
243 | self.env.filters['pycomment'] = filters.strings.python_comment | |||
|
244 | self.env.filters['rm_ansi'] = filters.ansi.remove_ansi | |||
|
245 | self.env.filters['rm_dollars'] = filters.strings.strip_dollars | |||
|
246 | self.env.filters['rm_fake'] = filters.strings.rm_fake | |||
|
247 | self.env.filters['rm_math_space'] = filters.latex.rm_math_space | |||
|
248 | self.env.filters['wrap'] = filters.strings.wrap | |||
|
249 | ||||
|
250 | ||||
246 | def _preprocess(self, nb): |
|
251 | def _preprocess(self, nb): | |
247 | """ Preprocess the notebook using the transformers specific |
|
252 | """ Preprocess the notebook using the transformers specific | |
248 | for the current export format. |
|
253 | for the current export format. | |
249 |
|
254 | |||
250 | nb: Notebook to preprocess |
|
255 | nb: Notebook to preprocess | |
251 | """ |
|
256 | """ | |
252 |
|
257 | |||
253 | #Dict of 'resources' that can be filled by the preprocessors. |
|
258 | #Dict of 'resources' that can be filled by the preprocessors. | |
254 | resources = {} |
|
259 | resources = {} | |
255 |
|
260 | |||
256 | #Run each transformer on the notebook. Carry the output along |
|
261 | #Run each transformer on the notebook. Carry the output along | |
257 | #to each transformer |
|
262 | #to each transformer | |
258 | for transformer in self.preprocessors: |
|
263 | for transformer in self.preprocessors: | |
259 | nb, resources = transformer(nb, resources) |
|
264 | nb, resources = transformer(nb, resources) | |
260 | return nb, resources |
|
265 | return nb, resources | |
261 |
|
266 | |||
262 |
|
||||
263 | def _get_default_options(self, export_format): |
|
|||
264 | """ Load the default options for built in formats. |
|
|||
265 |
|
||||
266 | export_format: Format being exported to. |
|
|||
267 | """ |
|
|||
268 |
|
||||
269 | c = get_config() |
|
|||
270 |
|
||||
271 | #Set default data extraction priorities. |
|
|||
272 | c.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
273 | c.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
274 | c.ConverterTemplate.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
275 |
|
||||
276 | #For most (or all cases), the template file name matches the format name. |
|
|||
277 | c.ConverterTemplate.template_file = export_format |
|
|||
278 |
|
||||
279 | if export_format == "basichtml" or "fullhtml" or "reveal": |
|
|||
280 | c.CSSHtmlHeaderTransformer.enabled=True |
|
|||
281 | if export_format == 'reveal' |
|
|||
282 | c.NbconvertApp.fileext='reveal.html' |
|
|||
283 | else: |
|
|||
284 | c.NbconvertApp.fileext='html' |
|
|||
285 |
|
||||
286 | elif export_format == "latex_sphinx_howto" or export_format == "latex_sphinx_manual": |
|
|||
287 |
|
||||
288 | #Turn on latex environment |
|
|||
289 | c.ConverterTemplate.tex_environement=True |
|
|||
290 |
|
||||
291 | #Standard latex extension |
|
|||
292 | c.NbconvertApp.fileext='tex' |
|
|||
293 |
|
||||
294 | #Prioritize latex extraction for latex exports. |
|
|||
295 | c.GlobalConfigurable.display_data_priority =['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text'] |
|
|||
296 | c.ExtractFigureTransformer.display_data_priority=['latex', 'svg', 'png', 'jpg', 'jpeg'] |
|
|||
297 | c.ExtractFigureTransformer.extra_ext_map={'svg':'pdf'} |
|
|||
298 | c.ExtractFigureTransformer.enabled=True |
|
|||
299 |
|
||||
300 | # Enable latex transformers (make markdown2latex work with math $.) |
|
|||
301 | c.LatexTransformer.enabled=True |
|
|||
302 | c.SphinxTransformer.enabled = True |
|
|||
303 |
|
||||
304 | elif export_format == 'markdown': |
|
|||
305 | c.NbconvertApp.fileext='md' |
|
|||
306 | c.ExtractFigureTransformer.enabled=True |
|
|||
307 |
|
||||
308 | elif export_format == 'python': |
|
|||
309 | c.NbconvertApp.fileext='py' |
|
|||
310 |
|
||||
311 |
|
||||
312 | elif export_format == 'rst': |
|
|||
313 | c.NbconvertApp.fileext='rst' |
|
|||
314 | c.ExtractFigureTransformer.enabled=True |
|
|||
315 | return c |
|
|||
316 |
|
||||
317 |
|
||||
318 | #TODO: Comment me. |
|
|||
319 | def _rm_fake(strng): |
|
|||
320 | return strng.replace('/files/', '') |
|
|||
321 |
|
||||
322 |
|
||||
323 | #TODO: Comment me. |
|
|||
324 | def _python_comment(string): |
|
|||
325 | return '# '+'\n# '.join(string.split('\n')) |
|
|||
326 |
|
||||
327 |
|
||||
328 | #TODO: Comment me. |
|
|||
329 | def _escape_tex(value): |
|
|||
330 | newval = value |
|
|||
331 | for pattern, replacement in LATEX_SUBS: |
|
|||
332 | newval = pattern.sub(replacement, newval) |
|
|||
333 | return newval No newline at end of file |
|
@@ -1,295 +1,150 b'' | |||||
1 |
|
||||
2 | """Latex exporter for the notebook conversion pipeline. |
|
1 | """Latex exporter for the notebook conversion pipeline. | |
3 |
|
2 | |||
4 | This module defines Exporter, a highly configurable converter |
|
3 | This module defines Exporter, a highly configurable converter | |
5 | that uses Jinja2 to export notebook files into different format. |
|
4 | that uses Jinja2 to export notebook files into different format. | |
6 |
|
5 | |||
7 | You can register both pre-transformers that will act on the notebook format |
|
6 | You can register both pre-transformers that will act on the notebook format | |
8 | befor conversion and jinja filter that would then be availlable in the templates |
|
7 | befor conversion and jinja filter that would then be availlable in the templates | |
9 | """ |
|
8 | """ | |
10 |
|
9 | |||
11 | #----------------------------------------------------------------------------- |
|
10 | #----------------------------------------------------------------------------- | |
12 | # Copyright (c) 2013, the IPython Development Team. |
|
11 | # Copyright (c) 2013, the IPython Development Team. | |
13 | # |
|
12 | # | |
14 | # Distributed under the terms of the Modified BSD License. |
|
13 | # Distributed under the terms of the Modified BSD License. | |
15 | # |
|
14 | # | |
16 | # The full license is in the file COPYING.txt, distributed with this software. |
|
15 | # The full license is in the file COPYING.txt, distributed with this software. | |
17 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
18 |
|
17 | |||
19 | #----------------------------------------------------------------------------- |
|
18 | #----------------------------------------------------------------------------- | |
20 | # Imports |
|
19 | # Imports | |
21 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
22 | from .utils import highlight2latex #TODO |
|
21 | import base.Exporter as Exporter | |
23 |
|
||||
24 | from .transformers.latex import LatexTransformer, rm_math_space #TODO: rm_math_space from filters |
|
|||
25 |
|
22 | |||
26 | #Try to import the Sphinx exporter. If the user doesn't have Sphinx isntalled |
|
23 | #Try to import the Sphinx exporter. If the user doesn't have Sphinx isntalled | |
27 | #on his/her machine, fail silently. |
|
24 | #on his/her machine, fail silently. | |
28 | try: |
|
25 | try: | |
29 | from .sphinx_transformer import (SphinxTransformer) #TODO |
|
26 | from .sphinx_transformer import (SphinxTransformer) #TODO | |
30 | except ImportError: |
|
27 | except ImportError: | |
31 | SphinxTransformer = None |
|
28 | SphinxTransformer = None | |
32 |
|
29 | |||
33 | #----------------------------------------------------------------------------- |
|
30 | #----------------------------------------------------------------------------- | |
34 | # Globals and constants |
|
31 | # Globals and constants | |
35 | #----------------------------------------------------------------------------- |
|
32 | #----------------------------------------------------------------------------- | |
36 |
|
33 | |||
37 | #Latex Jinja2 constants |
|
34 | #Latex Jinja2 constants | |
38 | LATEX_TEMPLATE_PATH = "/../templates/tex/" |
|
35 | LATEX_TEMPLATE_PATH = "/../templates/tex/" | |
39 | LATEX_TEMPLATE_SKELETON_PATH = "/../templates/tex/skeleton/" |
|
36 | LATEX_TEMPLATE_SKELETON_PATH = "/../templates/tex/skeleton/" | |
40 | LATEX_TEMPLATE_EXTENSION = ".tplx" |
|
37 | LATEX_TEMPLATE_EXTENSION = ".tplx" | |
41 |
|
38 | |||
42 | #Special Jinja2 syntax that will not conflict when exporting latex. |
|
39 | #Special Jinja2 syntax that will not conflict when exporting latex. | |
43 | LATEX_JINJA_COMMENT_BLOCK = ["((=", "=))"] |
|
40 | LATEX_JINJA_COMMENT_BLOCK = ["((=", "=))"] | |
44 | LATEX_JINJA_VARIABLE_BLOCK = ["(((", ")))"] |
|
41 | LATEX_JINJA_VARIABLE_BLOCK = ["(((", ")))"] | |
45 | LATEX_JINJA_LOGIC_BLOCK = ["((*", "*))"] |
|
42 | LATEX_JINJA_LOGIC_BLOCK = ["((*", "*))"] | |
46 |
|
43 | |||
47 | #Latex substitutions for escaping latex. |
|
|||
48 | LATEX_SUBS = ( |
|
|||
49 | (re.compile(r'\\'), r'\\textbackslash'), |
|
|||
50 | (re.compile(r'([{}_#%&$])'), r'\\\1'), |
|
|||
51 | (re.compile(r'~'), r'\~{}'), |
|
|||
52 | (re.compile(r'\^'), r'\^{}'), |
|
|||
53 | (re.compile(r'"'), r"''"), |
|
|||
54 | (re.compile(r'\.\.\.+'), r'\\ldots'), |
|
|||
55 | ) |
|
|||
56 |
|
||||
57 | #----------------------------------------------------------------------------- |
|
44 | #----------------------------------------------------------------------------- | |
58 | # Classes and functions |
|
45 | # Classes and functions | |
59 | #----------------------------------------------------------------------------- |
|
46 | #----------------------------------------------------------------------------- | |
60 |
class LatexExporter( |
|
47 | class LatexExporter(Exporter): | |
61 | """ A Jinja2 base converter templates |
|
48 | """ A Jinja2 base converter templates | |
62 |
|
49 | |||
63 | Preprocess the ipynb files, feed it throug jinja templates, |
|
50 | Preprocess the ipynb files, feed it throug jinja templates, | |
64 | and spit an converted files and a data object with other data |
|
51 | and spit an converted files and a data object with other data | |
65 | should be mostly configurable |
|
52 | should be mostly configurable | |
66 | """ |
|
53 | """ | |
67 |
|
54 | |||
68 | #Processors that process the input data prior to the export, set in the |
|
55 | #Processors that process the input data prior to the export, set in the | |
69 | #constructor for this class. |
|
56 | #constructor for this class. | |
70 | preprocessors = [] |
|
57 | preprocessors = [] | |
71 |
|
58 | |||
72 | def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw): |
|
59 | def __init__(self, preprocessors={}, jinja_filters={}, config=None, export_format, **kw): | |
73 | """ Init a new converter. |
|
60 | """ Init a new converter. | |
74 |
|
61 | |||
75 | config: the Configurable config object to pass around. |
|
62 | config: the Configurable config object to pass around. | |
76 |
|
63 | |||
77 | preprocessors: dict of **availlable** key/value function to run on |
|
64 | preprocessors: dict of **availlable** key/value function to run on | |
78 | ipynb json data before conversion to extract/inline file. |
|
65 | ipynb json data before conversion to extract/inline file. | |
79 | See `transformer.py` and `ConfigurableTransformers` |
|
66 | See `transformer.py` and `ConfigurableTransformers` | |
80 |
|
67 | |||
81 | set the order in which the transformers should apply |
|
68 | set the order in which the transformers should apply | |
82 | with the `pre_transformer_order` trait of this class |
|
69 | with the `pre_transformer_order` trait of this class | |
83 |
|
70 | |||
84 | transformers registerd by this key will take precedence on |
|
71 | transformers registerd by this key will take precedence on | |
85 | default one. |
|
72 | default one. | |
86 |
|
73 | |||
87 | jinja_filters: dict of supplementary jinja filter that should be made |
|
74 | jinja_filters: dict of supplementary jinja filter that should be made | |
88 | availlable in template. If those are of Configurable Class type, |
|
75 | availlable in template. If those are of Configurable Class type, | |
89 | they will be instanciated with the config object as argument. |
|
76 | they will be instanciated with the config object as argument. | |
90 |
|
77 | |||
91 | user defined filter will overwrite the one availlable by default. |
|
78 | user defined filter will overwrite the one availlable by default. | |
92 | """ |
|
79 | """ | |
93 |
|
80 | |||
94 | #Merge default config options with user specific override options. |
|
81 | #Merge default config options with user specific override options. | |
95 | default_config = self._get_default_options() |
|
82 | default_config = self._get_default_options() | |
96 | if not config == None: |
|
83 | if not config == None: | |
97 | default_config._merge(config) |
|
84 | default_config._merge(config) | |
98 | config = default_config |
|
85 | config = default_config | |
99 |
|
86 | |||
100 | #Call the base class constructor |
|
87 | #Call the base class constructor | |
101 | super(Exporter, self).__init__(config=config, **kw) |
|
88 | super(Exporter, self).__init__(config=config, **kw) | |
102 |
|
89 | |||
103 | #Create a Latex environment if the user is exporting latex. |
|
90 | #Create a Latex environment if the user is exporting latex. | |
104 | if self.tex_environement: |
|
91 | if self.tex_environement: | |
105 | self.ext = LATEX_TEMPLATE_EXTENSION |
|
92 | self.ext = LATEX_TEMPLATE_EXTENSION | |
106 | self.env = Environment( |
|
93 | self.env = Environment( | |
107 | loader=FileSystemLoader([ |
|
94 | loader=FileSystemLoader([ | |
108 | os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_PATH, |
|
95 | os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_PATH, | |
109 | os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_SKELETON_PATH, |
|
96 | os.path.dirname(os.path.realpath(__file__)) + LATEX_TEMPLATE_SKELETON_PATH, | |
110 | ]), |
|
97 | ]), | |
111 | extensions=JINJA_EXTENSIONS |
|
98 | extensions=JINJA_EXTENSIONS | |
112 | ) |
|
99 | ) | |
113 |
|
100 | |||
114 | #Set special Jinja2 syntax that will not conflict with latex. |
|
101 | #Set special Jinja2 syntax that will not conflict with latex. | |
115 | self.env.block_start_string = LATEX_JINJA_LOGIC_BLOCK[0] |
|
102 | self.env.block_start_string = LATEX_JINJA_LOGIC_BLOCK[0] | |
116 | self.env.block_end_string = LATEX_JINJA_LOGIC_BLOCK[1] |
|
103 | self.env.block_end_string = LATEX_JINJA_LOGIC_BLOCK[1] | |
117 | self.env.variable_start_string = LATEX_JINJA_VARIABLE_BLOCK[0] |
|
104 | self.env.variable_start_string = LATEX_JINJA_VARIABLE_BLOCK[0] | |
118 | self.env.variable_end_string = LATEX_JINJA_VARIABLE_BLOCK[1] |
|
105 | self.env.variable_end_string = LATEX_JINJA_VARIABLE_BLOCK[1] | |
119 | self.env.comment_start_string = LATEX_JINJA_COMMENT_BLOCK[0] |
|
106 | self.env.comment_start_string = LATEX_JINJA_COMMENT_BLOCK[0] | |
120 | self.env.comment_end_string = LATEX_JINJA_COMMENT_BLOCK[1] |
|
107 | self.env.comment_end_string = LATEX_JINJA_COMMENT_BLOCK[1] | |
121 |
|
108 | |||
122 | else: #Standard environment |
|
109 | else: #Standard environment | |
123 | self.ext = TEMPLATE_EXTENSION |
|
110 | self.ext = TEMPLATE_EXTENSION | |
124 | self.env = Environment( |
|
111 | self.env = Environment( | |
125 | loader=FileSystemLoader([ |
|
112 | loader=FileSystemLoader([ | |
126 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH, |
|
113 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_PATH, | |
127 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH, |
|
114 | os.path.dirname(os.path.realpath(__file__)) + TEMPLATE_SKELETON_PATH, | |
128 | ]), |
|
115 | ]), | |
129 | extensions=JINJA_EXTENSIONS |
|
116 | extensions=JINJA_EXTENSIONS | |
130 | ) |
|
117 | ) | |
131 |
|
118 | |||
132 | for name in self.pre_transformer_order: |
|
119 | for name in self.pre_transformer_order: | |
133 | # get the user-defined transformer first |
|
120 | # get the user-defined transformer first | |
134 | transformer = preprocessors.get(name, getattr(trans, name, None)) |
|
121 | transformer = preprocessors.get(name, getattr(trans, name, None)) | |
135 | if isinstance(transformer, MetaHasTraits): |
|
122 | if isinstance(transformer, MetaHasTraits): | |
136 | transformer = transformer(config=config) |
|
123 | transformer = transformer(config=config) | |
137 | self.preprocessors.append(transformer) |
|
124 | self.preprocessors.append(transformer) | |
138 |
|
125 | |||
139 | #For compatibility, TODO: remove later. |
|
126 | #For compatibility, TODO: remove later. | |
140 | self.preprocessors.append(trans.coalesce_streams) |
|
127 | self.preprocessors.append(trans.coalesce_streams) | |
141 | self.preprocessors.append(trans.ExtractFigureTransformer(config=config)) |
|
128 | self.preprocessors.append(trans.ExtractFigureTransformer(config=config)) | |
142 | self.preprocessors.append(trans.RevealHelpTransformer(config=config)) |
|
129 | self.preprocessors.append(trans.RevealHelpTransformer(config=config)) | |
143 | self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config)) |
|
130 | self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config)) | |
144 | self.preprocessors.append(LatexTransformer(config=config)) |
|
131 | self.preprocessors.append(LatexTransformer(config=config)) | |
145 |
|
132 | |||
146 | #Only load the sphinx transformer if the file reference worked |
|
133 | #Only load the sphinx transformer if the file reference worked | |
147 | #(Sphinx dependencies exist on the user's machine.) |
|
134 | #(Sphinx dependencies exist on the user's machine.) | |
148 | if SphinxTransformer: |
|
135 | if SphinxTransformer: | |
149 | self.preprocessors.append(SphinxTransformer(config=config)) |
|
136 | self.preprocessors.append(SphinxTransformer(config=config)) | |
150 |
|
137 | |||
151 | #Add filters to the Jinja2 environment |
|
138 | #Add filters to the Jinja2 environment | |
152 | self.env.filters['filter_data_type'] = DataTypeFilter(config=config) |
|
139 | self.env.filters['escape_tex'] = filters.latex.escape_tex | |
153 | self.env.filters['pycomment'] = _python_comment |
|
140 | self.env.filters['highlight'] = filters.pygments.highlight2latex | |
154 | self.env.filters['indent'] = indent |
|
|||
155 | self.env.filters['rm_fake'] = _rm_fake |
|
|||
156 | self.env.filters['rm_ansi'] = remove_ansi |
|
|||
157 | self.env.filters['markdown'] = markdown |
|
|||
158 | self.env.filters['ansi2html'] = ansi2html |
|
|||
159 | self.env.filters['markdown2latex'] = markdown_utils.markdown2latex |
|
|||
160 | self.env.filters['markdown2rst'] = markdown_utils.markdown2rst |
|
|||
161 | self.env.filters['get_lines'] = get_lines |
|
|||
162 | self.env.filters['wrap'] = strings.wrap |
|
|||
163 | self.env.filters['rm_dollars'] = strings.strip_dollars |
|
|||
164 | self.env.filters['rm_math_space'] = rm_math_space |
|
|||
165 | self.env.filters['highlight2html'] = highlight |
|
|||
166 | self.env.filters['highlight2latex'] = highlight2latex |
|
|||
167 |
|
||||
168 | #Latex specific filters |
|
|||
169 | if self.tex_environement: |
|
|||
170 | self.env.filters['escape_tex'] = _escape_tex |
|
|||
171 | self.env.filters['highlight'] = highlight2latex |
|
|||
172 | else: |
|
|||
173 | self.env.filters['highlight'] = highlight |
|
|||
174 |
|
141 | |||
175 | #Load user filters. Overwrite existing filters if need be. |
|
142 | #Load user filters. Overwrite existing filters if need be. | |
176 | for key, user_filter in jinja_filters.iteritems(): |
|
143 | for key, user_filter in jinja_filters.iteritems(): | |
177 | if isinstance(user_filter, MetaHasTraits): |
|
144 | if isinstance(user_filter, MetaHasTraits): | |
178 | self.env.filters[key] = user_filter(config=config) |
|
145 | self.env.filters[key] = user_filter(config=config) | |
179 | else: |
|
146 | else: | |
180 | self.env.filters[key] = user_filter |
|
147 | self.env.filters[key] = user_filter | |
181 |
|
148 | |||
182 | #Load the template file. |
|
149 | #Load the template file. | |
183 | self.template = self.env.get_template(self.template_file+self.ext) |
|
150 | self.template = self.env.get_template(self.template_file+self.ext) | |
184 |
|
||||
185 |
|
||||
186 | def export(self, nb): |
|
|||
187 | """Export notebook object |
|
|||
188 |
|
||||
189 | nb: Notebook object to export. |
|
|||
190 |
|
||||
191 | Returns both the converted ipynb file and a dict containing the |
|
|||
192 | resources created along the way via the transformers and Jinja2 |
|
|||
193 | processing. |
|
|||
194 | """ |
|
|||
195 |
|
||||
196 | nb, resources = self._preprocess(nb) |
|
|||
197 | return self.template.render(nb=nb, resources=resources), resources |
|
|||
198 |
|
||||
199 |
|
||||
200 | def from_filename(self, filename): |
|
|||
201 | """Read and export a notebook from a filename |
|
|||
202 |
|
||||
203 | filename: Filename of the notebook file to export. |
|
|||
204 |
|
||||
205 | Returns both the converted ipynb file and a dict containing the |
|
|||
206 | resources created along the way via the transformers and Jinja2 |
|
|||
207 | processing. |
|
|||
208 | """ |
|
|||
209 | with io.open(filename) as f: |
|
|||
210 | return self.export(nbformat.read(f, 'json')) |
|
|||
211 |
|
||||
212 |
|
||||
213 | def from_file(self, file_stream): |
|
|||
214 | """Read and export a notebook from a filename |
|
|||
215 |
|
||||
216 | file_stream: File handle of file that contains notebook data. |
|
|||
217 |
|
||||
218 | Returns both the converted ipynb file and a dict containing the |
|
|||
219 | resources created along the way via the transformers and Jinja2 |
|
|||
220 | processing. |
|
|||
221 | """ |
|
|||
222 |
|
||||
223 | return self.export(nbformat.read(file_stream, 'json')) |
|
|||
224 |
|
||||
225 |
|
||||
226 | def _preprocess(self, nb): |
|
|||
227 | """ Preprocess the notebook using the transformers specific |
|
|||
228 | for the current export format. |
|
|||
229 |
|
||||
230 | nb: Notebook to preprocess |
|
|||
231 | """ |
|
|||
232 |
|
||||
233 | #Dict of 'resources' that can be filled by the preprocessors. |
|
|||
234 | resources = {} |
|
|||
235 |
|
||||
236 | #Run each transformer on the notebook. Carry the output along |
|
|||
237 | #to each transformer |
|
|||
238 | for transformer in self.preprocessors: |
|
|||
239 | nb, resources = transformer(nb, resources) |
|
|||
240 | return nb, resources |
|
|||
241 |
|
||||
242 |
|
||||
243 | def _get_default_options(self, export_format): |
|
|||
244 | """ Load the default options for built in formats. |
|
|||
245 |
|
||||
246 | export_format: Format being exported to. |
|
|||
247 | """ |
|
|||
248 |
|
||||
249 | c = get_config() |
|
|||
250 |
|
||||
251 | #Set default data extraction priorities. |
|
|||
252 | c.GlobalConfigurable.display_data_priority =['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
253 | c.ExtractFigureTransformer.display_data_priority=['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
254 | c.ConverterTemplate.display_data_priority= ['svg', 'png', 'latex', 'jpg', 'jpeg','text'] |
|
|||
255 |
|
||||
256 | #For most (or all cases), the template file name matches the format name. |
|
|||
257 | c.ConverterTemplate.template_file = export_format |
|
|||
258 |
|
||||
259 | if export_format == "basichtml" or "fullhtml" or "reveal": |
|
|||
260 | c.CSSHtmlHeaderTransformer.enabled=True |
|
|||
261 | if export_format == 'reveal' |
|
|||
262 | c.NbconvertApp.fileext='reveal.html' |
|
|||
263 | else: |
|
|||
264 | c.NbconvertApp.fileext='html' |
|
|||
265 |
|
||||
266 | elif export_format == "latex_sphinx_howto" or export_format == "latex_sphinx_manual": |
|
|||
267 |
|
||||
268 | #Turn on latex environment |
|
|||
269 | c.ConverterTemplate.tex_environement=True |
|
|||
270 |
|
||||
271 | #Standard latex extension |
|
|||
272 | c.NbconvertApp.fileext='tex' |
|
|||
273 |
|
||||
274 | #Prioritize latex extraction for latex exports. |
|
|||
275 | c.GlobalConfigurable.display_data_priority =['latex', 'svg', 'png', 'jpg', 'jpeg' , 'text'] |
|
|||
276 | c.ExtractFigureTransformer.display_data_priority=['latex', 'svg', 'png', 'jpg', 'jpeg'] |
|
|||
277 | c.ExtractFigureTransformer.extra_ext_map={'svg':'pdf'} |
|
|||
278 | c.ExtractFigureTransformer.enabled=True |
|
|||
279 |
|
||||
280 | # Enable latex transformers (make markdown2latex work with math $.) |
|
|||
281 | c.LatexTransformer.enabled=True |
|
|||
282 | c.SphinxTransformer.enabled = True |
|
|||
283 |
|
||||
284 | elif export_format == 'markdown': |
|
|||
285 | c.NbconvertApp.fileext='md' |
|
|||
286 | c.ExtractFigureTransformer.enabled=True |
|
|||
287 |
|
||||
288 | elif export_format == 'python': |
|
|||
289 | c.NbconvertApp.fileext='py' |
|
|||
290 |
|
||||
291 |
|
||||
292 | elif export_format == 'rst': |
|
|||
293 | c.NbconvertApp.fileext='rst' |
|
|||
294 | c.ExtractFigureTransformer.enabled=True |
|
|||
295 | return c No newline at end of file |
|
@@ -1,31 +1,31 b'' | |||||
1 | """Filter used to select the first prefered output format available. |
|
1 | """Filter used to select the first prefered output format available. | |
2 |
|
2 | |||
3 | The filter contained in the file allows the converter templates to select |
|
3 | The filter contained in the file allows the converter templates to select | |
4 | the output format that is most valuable to the active export format. The |
|
4 | the output format that is most valuable to the active export format. The | |
5 | value of the different formats is set via |
|
5 | value of the different formats is set via | |
6 | GlobalConfigurable.display_data_priority |
|
6 | GlobalConfigurable.display_data_priority | |
7 | """ |
|
7 | """ | |
8 | #----------------------------------------------------------------------------- |
|
8 | #----------------------------------------------------------------------------- | |
9 | # Copyright (c) 2013, the IPython Development Team. |
|
9 | # Copyright (c) 2013, the IPython Development Team. | |
10 | # |
|
10 | # | |
11 | # Distributed under the terms of the Modified BSD License. |
|
11 | # Distributed under the terms of the Modified BSD License. | |
12 | # |
|
12 | # | |
13 | # The full license is in the file COPYING.txt, distributed with this software. |
|
13 | # The full license is in the file COPYING.txt, distributed with this software. | |
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 |
|
15 | |||
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 | # Classes and functions |
|
17 | # Classes and functions | |
18 | #----------------------------------------------------------------------------- |
|
18 | #----------------------------------------------------------------------------- | |
19 | class DataTypeFilter(GlobalConfigurable): |
|
19 | class DataTypeFilter(GlobalConfigurable): | |
20 | """ Returns the prefered display format """ |
|
20 | """ Returns the prefered display format """ | |
21 |
|
21 | |||
22 | def __init__(self, config=None, **kw): |
|
22 | def __init__(self, config=None, **kw): | |
23 |
super( |
|
23 | super(DataTypeFilter, self).__init__(config=config, **kw) | |
24 |
|
24 | |||
25 | def __call__(self, output): |
|
25 | def __call__(self, output): | |
26 | """ Return the first available format in the priority """ |
|
26 | """ Return the first available format in the priority """ | |
27 |
|
27 | |||
28 | for fmt in self.display_data_priority: |
|
28 | for fmt in self.display_data_priority: | |
29 | if fmt in output: |
|
29 | if fmt in output: | |
30 | return [fmt] |
|
30 | return [fmt] | |
31 | return [] No newline at end of file |
|
31 | return [] |
@@ -1,72 +1,95 b'' | |||||
1 | """Latex transformer. |
|
1 | """Latex transformer. | |
2 |
|
2 | |||
3 | Module that allows latex output notebooks to be conditioned before |
|
3 | Module that allows latex output notebooks to be conditioned before | |
4 | they are converted. |
|
4 | they are converted. | |
5 | """ |
|
5 | """ | |
6 | #----------------------------------------------------------------------------- |
|
6 | #----------------------------------------------------------------------------- | |
7 | # Copyright (c) 2013, the IPython Development Team. |
|
7 | # Copyright (c) 2013, the IPython Development Team. | |
8 | # |
|
8 | # | |
9 | # Distributed under the terms of the Modified BSD License. |
|
9 | # Distributed under the terms of the Modified BSD License. | |
10 | # |
|
10 | # | |
11 | # The full license is in the file COPYING.txt, distributed with this software. |
|
11 | # The full license is in the file COPYING.txt, distributed with this software. | |
12 | #----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 |
|
13 | |||
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | # Imports |
|
15 | # Imports | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 | from __future__ import print_function |
|
17 | import re | |
|
18 | ||||
|
19 | #----------------------------------------------------------------------------- | |||
|
20 | # Globals and constants | |||
|
21 | #----------------------------------------------------------------------------- | |||
|
22 | ||||
|
23 | #Latex substitutions for escaping latex. | |||
|
24 | LATEX_SUBS = ( | |||
|
25 | (re.compile(r'\\'), r'\\textbackslash'), | |||
|
26 | (re.compile(r'([{}_#%&$])'), r'\\\1'), | |||
|
27 | (re.compile(r'~'), r'\~{}'), | |||
|
28 | (re.compile(r'\^'), r'\^{}'), | |||
|
29 | (re.compile(r'"'), r"''"), | |||
|
30 | (re.compile(r'\.\.\.+'), r'\\ldots'), | |||
|
31 | ) | |||
18 |
|
32 | |||
19 | #----------------------------------------------------------------------------- |
|
33 | #----------------------------------------------------------------------------- | |
20 | # Functions |
|
34 | # Functions | |
21 | #----------------------------------------------------------------------------- |
|
35 | #----------------------------------------------------------------------------- | |
|
36 | ||||
|
37 | #TODO: Comment me. | |||
|
38 | def escape_tex(value): | |||
|
39 | newval = value | |||
|
40 | for pattern, replacement in LATEX_SUBS: | |||
|
41 | newval = pattern.sub(replacement, newval) | |||
|
42 | return newval | |||
|
43 | ||||
|
44 | ||||
22 | def rm_math_space(text): |
|
45 | def rm_math_space(text): | |
23 | """ |
|
46 | """ | |
24 | Remove the space between latex math commands and enclosing $ symbols. |
|
47 | Remove the space between latex math commands and enclosing $ symbols. | |
25 | """ |
|
48 | """ | |
26 |
|
49 | |||
27 | # First, scan through the markdown looking for $. If |
|
50 | # First, scan through the markdown looking for $. If | |
28 | # a $ symbol is found, without a preceding \, assume |
|
51 | # a $ symbol is found, without a preceding \, assume | |
29 | # it is the start of a math block. UNLESS that $ is |
|
52 | # it is the start of a math block. UNLESS that $ is | |
30 | # not followed by another within two math_lines. |
|
53 | # not followed by another within two math_lines. | |
31 | math_regions = [] |
|
54 | math_regions = [] | |
32 | math_lines = 0 |
|
55 | math_lines = 0 | |
33 | within_math = False |
|
56 | within_math = False | |
34 | math_start_index = 0 |
|
57 | math_start_index = 0 | |
35 | ptext = '' |
|
58 | ptext = '' | |
36 | last_character = "" |
|
59 | last_character = "" | |
37 | skip = False |
|
60 | skip = False | |
38 | for index, char in enumerate(text): |
|
61 | for index, char in enumerate(text): | |
39 |
|
62 | |||
40 | #Make sure the character isn't preceeded by a backslash |
|
63 | #Make sure the character isn't preceeded by a backslash | |
41 | if (char == "$" and last_character != "\\"): |
|
64 | if (char == "$" and last_character != "\\"): | |
42 |
|
65 | |||
43 | # Close the math region if this is an ending $ |
|
66 | # Close the math region if this is an ending $ | |
44 | if within_math: |
|
67 | if within_math: | |
45 | within_math = False |
|
68 | within_math = False | |
46 | skip = True |
|
69 | skip = True | |
47 | ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$' |
|
70 | ptext = ptext+'$'+text[math_start_index+1:index].strip()+'$' | |
48 | math_regions.append([math_start_index, index+1]) |
|
71 | math_regions.append([math_start_index, index+1]) | |
49 | else: |
|
72 | else: | |
50 |
|
73 | |||
51 | # Start a new math region |
|
74 | # Start a new math region | |
52 | within_math = True |
|
75 | within_math = True | |
53 | math_start_index = index |
|
76 | math_start_index = index | |
54 | math_lines = 0 |
|
77 | math_lines = 0 | |
55 |
|
78 | |||
56 | # If we are in a math region, count the number of lines parsed. |
|
79 | # If we are in a math region, count the number of lines parsed. | |
57 | # Cancel the math region if we find two line breaks! |
|
80 | # Cancel the math region if we find two line breaks! | |
58 | elif char == "\n": |
|
81 | elif char == "\n": | |
59 | if within_math: |
|
82 | if within_math: | |
60 | math_lines += 1 |
|
83 | math_lines += 1 | |
61 | if math_lines > 1: |
|
84 | if math_lines > 1: | |
62 | within_math = False |
|
85 | within_math = False | |
63 | ptext = ptext+text[math_start_index:index] |
|
86 | ptext = ptext+text[math_start_index:index] | |
64 |
|
87 | |||
65 | # Remember the last character so we can easily watch |
|
88 | # Remember the last character so we can easily watch | |
66 | # for backslashes |
|
89 | # for backslashes | |
67 | last_character = char |
|
90 | last_character = char | |
68 | if not within_math and not skip: |
|
91 | if not within_math and not skip: | |
69 | ptext = ptext+char |
|
92 | ptext = ptext+char | |
70 | if skip: |
|
93 | if skip: | |
71 | skip = False |
|
94 | skip = False | |
72 | return ptext |
|
95 | return ptext |
@@ -1,75 +1,77 b'' | |||||
1 | """Markdown utilities |
|
1 | """Markdown utilities | |
2 |
|
2 | |||
3 | This file contains a collection of utility functions for dealing with |
|
3 | This file contains a collection of utility functions for dealing with | |
4 | markdown. |
|
4 | markdown. | |
5 | """ |
|
5 | """ | |
6 | #----------------------------------------------------------------------------- |
|
6 | #----------------------------------------------------------------------------- | |
7 | # Copyright (c) 2013, the IPython Development Team. |
|
7 | # Copyright (c) 2013, the IPython Development Team. | |
8 | # |
|
8 | # | |
9 | # Distributed under the terms of the Modified BSD License. |
|
9 | # Distributed under the terms of the Modified BSD License. | |
10 | # |
|
10 | # | |
11 | # The full license is in the file COPYING.txt, distributed with this software. |
|
11 | # The full license is in the file COPYING.txt, distributed with this software. | |
12 | #----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 |
|
13 | |||
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | # Imports |
|
15 | # Imports | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 | from __future__ import print_function |
|
17 | from __future__ import print_function | |
18 |
|
18 | |||
19 | # Stdlib imports |
|
19 | # Stdlib imports | |
|
20 | import sys | |||
20 | import subprocess |
|
21 | import subprocess | |
21 |
|
22 | |||
22 | #----------------------------------------------------------------------------- |
|
23 | #----------------------------------------------------------------------------- | |
23 | # Functions |
|
24 | # Functions | |
24 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
|
26 | ||||
25 | # Pandoc-dependent code |
|
27 | # Pandoc-dependent code | |
26 | def markdown2latex(src): |
|
28 | def markdown2latex(src): | |
27 | """Convert a markdown string to LaTeX via pandoc. |
|
29 | """Convert a markdown string to LaTeX via pandoc. | |
28 |
|
30 | |||
29 | This function will raise an error if pandoc is not installed. |
|
31 | This function will raise an error if pandoc is not installed. | |
30 |
|
32 | |||
31 | Any error messages generated by pandoc are printed to stderr. |
|
33 | Any error messages generated by pandoc are printed to stderr. | |
32 |
|
34 | |||
33 | Parameters |
|
35 | Parameters | |
34 | ---------- |
|
36 | ---------- | |
35 | src : string |
|
37 | src : string | |
36 | Input string, assumed to be valid markdown. |
|
38 | Input string, assumed to be valid markdown. | |
37 |
|
39 | |||
38 | Returns |
|
40 | Returns | |
39 | ------- |
|
41 | ------- | |
40 | out : string |
|
42 | out : string | |
41 | Output as returned by pandoc. |
|
43 | Output as returned by pandoc. | |
42 | """ |
|
44 | """ | |
43 | p = subprocess.Popen('pandoc -f markdown -t latex'.split(), |
|
45 | p = subprocess.Popen('pandoc -f markdown -t latex'.split(), | |
44 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
|
46 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
45 | out, err = p.communicate(src.encode('utf-8')) |
|
47 | out, err = p.communicate(src.encode('utf-8')) | |
46 | if err: |
|
48 | if err: | |
47 | print(err, file=sys.stderr) |
|
49 | print(err, file=sys.stderr) | |
48 | #print('*'*20+'\n', out, '\n'+'*'*20) # dbg |
|
50 | #print('*'*20+'\n', out, '\n'+'*'*20) # dbg | |
49 | return unicode(out, 'utf-8') |
|
51 | return unicode(out, 'utf-8') | |
50 |
|
52 | |||
51 |
|
53 | |||
52 | def markdown2rst(src): |
|
54 | def markdown2rst(src): | |
53 | """Convert a markdown string to LaTeX via pandoc. |
|
55 | """Convert a markdown string to LaTeX via pandoc. | |
54 |
|
56 | |||
55 | This function will raise an error if pandoc is not installed. |
|
57 | This function will raise an error if pandoc is not installed. | |
56 |
|
58 | |||
57 | Any error messages generated by pandoc are printed to stderr. |
|
59 | Any error messages generated by pandoc are printed to stderr. | |
58 |
|
60 | |||
59 | Parameters |
|
61 | Parameters | |
60 | ---------- |
|
62 | ---------- | |
61 | src : string |
|
63 | src : string | |
62 | Input string, assumed to be valid markdown. |
|
64 | Input string, assumed to be valid markdown. | |
63 |
|
65 | |||
64 | Returns |
|
66 | Returns | |
65 | ------- |
|
67 | ------- | |
66 | out : string |
|
68 | out : string | |
67 | Output as returned by pandoc. |
|
69 | Output as returned by pandoc. | |
68 | """ |
|
70 | """ | |
69 | p = subprocess.Popen('pandoc -f markdown -t rst'.split(), |
|
71 | p = subprocess.Popen('pandoc -f markdown -t rst'.split(), | |
70 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) |
|
72 | stdin=subprocess.PIPE, stdout=subprocess.PIPE) | |
71 | out, err = p.communicate(src.encode('utf-8')) |
|
73 | out, err = p.communicate(src.encode('utf-8')) | |
72 | if err: |
|
74 | if err: | |
73 | print(err, file=sys.stderr) |
|
75 | print(err, file=sys.stderr) | |
74 | #print('*'*20+'\n', out, '\n'+'*'*20) # dbg |
|
76 | #print('*'*20+'\n', out, '\n'+'*'*20) # dbg | |
75 | return unicode(out, 'utf-8') No newline at end of file |
|
77 | return unicode(out, 'utf-8') |
@@ -1,35 +1,57 b'' | |||||
1 |
|
|
1 | """String utilities. | |
2 |
|
2 | |||
3 | Contains a collection of usefull string manipulations functions. |
|
3 | Contains a collection of usefull string manipulations functions. | |
4 | """ |
|
4 | """ | |
5 | #----------------------------------------------------------------------------- |
|
5 | #----------------------------------------------------------------------------- | |
6 | # Copyright (c) 2013, the IPython Development Team. |
|
6 | # Copyright (c) 2013, the IPython Development Team. | |
7 | # |
|
7 | # | |
8 | # Distributed under the terms of the Modified BSD License. |
|
8 | # Distributed under the terms of the Modified BSD License. | |
9 | # |
|
9 | # | |
10 | # The full license is in the file COPYING.txt, distributed with this software. |
|
10 | # The full license is in the file COPYING.txt, distributed with this software. | |
11 | #----------------------------------------------------------------------------- |
|
11 | #----------------------------------------------------------------------------- | |
12 |
|
12 | |||
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 | # Imports |
|
14 | # Imports | |
15 | #----------------------------------------------------------------------------- |
|
15 | #----------------------------------------------------------------------------- | |
16 |
|
16 | |||
17 | # Our own imports |
|
17 | # Our own imports | |
18 | import textwrap #TODO |
|
18 | import textwrap #TODO | |
19 |
|
19 | |||
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 | # Functions |
|
21 | # Functions | |
22 | #----------------------------------------------------------------------------- |
|
22 | #----------------------------------------------------------------------------- | |
23 | def wrap(text, width=100): |
|
23 | def wrap(text, width=100): | |
24 | """ Intelligently wrap text""" |
|
24 | """ Intelligently wrap text""" | |
25 |
|
25 | |||
26 | splitt = text.split('\n') |
|
26 | splitt = text.split('\n') | |
27 | wrp = map(lambda x:textwrap.wrap(x,width),splitt) |
|
27 | wrp = map(lambda x:textwrap.wrap(x,width),splitt) | |
28 | wrpd = map('\n'.join, wrp) |
|
28 | wrpd = map('\n'.join, wrp) | |
29 | return '\n'.join(wrpd) |
|
29 | return '\n'.join(wrpd) | |
30 |
|
30 | |||
31 |
|
31 | |||
32 | def strip_dollars(text): |
|
32 | def strip_dollars(text): | |
33 | """Remove all dollar symbols from text""" |
|
33 | """Remove all dollar symbols from text""" | |
34 |
|
34 | |||
35 | return text.strip('$') |
|
35 | return text.strip('$') | |
|
36 | ||||
|
37 | ||||
|
38 | #TODO: Comment me. | |||
|
39 | def rm_fake(strng): | |||
|
40 | return strng.replace('/files/', '') | |||
|
41 | ||||
|
42 | ||||
|
43 | #TODO: Comment me. | |||
|
44 | def python_comment(string): | |||
|
45 | return '# '+'\n# '.join(string.split('\n')) | |||
|
46 | ||||
|
47 | def get_lines(src, start=None,end=None): | |||
|
48 | """ | |||
|
49 | Split the input text into separate lines and then return the | |||
|
50 | lines that the caller is interested in. | |||
|
51 | """ | |||
|
52 | ||||
|
53 | # Split the input into lines. | |||
|
54 | lines = src.split("\n") | |||
|
55 | ||||
|
56 | # Return the right lines. | |||
|
57 | return "\n".join(lines[start:end]) #re-join |
@@ -1,18 +1,19 b'' | |||||
|
1 | from transformers.base import ConfigurableTransformers | |||
|
2 | ||||
1 |
|
3 | |||
2 | class ActivatableTransformer(ConfigurableTransformers): |
|
4 | class ActivatableTransformer(ConfigurableTransformers): | |
3 | """A simple ConfigurableTransformers that have an enabled flag |
|
5 | """A simple ConfigurableTransformers that have an enabled flag | |
4 |
|
6 | |||
5 | Inherit from that if you just want to have a transformer which is |
|
7 | Inherit from that if you just want to have a transformer which is | |
6 | no-op by default but can be activated in profiles with |
|
8 | no-op by default but can be activated in profiles with | |
7 |
|
9 | |||
8 | c.YourTransformerName.enabled = True |
|
10 | c.YourTransformerName.enabled = True | |
9 | """ |
|
11 | """ | |
10 |
|
12 | |||
11 | enabled = Bool(False, config=True) |
|
13 | enabled = Bool(False, config=True) | |
12 |
|
14 | |||
13 | def __call__(self, nb, other): |
|
15 | def __call__(self, nb, other): | |
14 | if not self.enabled : |
|
16 | if not self.enabled : | |
15 | return nb, other |
|
17 | return nb, other | |
16 | else : |
|
18 | else : | |
17 | return super(ActivatableTransformer, self).__call__(nb, other) |
|
19 | return super(ActivatableTransformer, self).__call__(nb, other) | |
18 |
|
@@ -1,120 +1,121 b'' | |||||
1 | """ |
|
1 | """ | |
2 | Module that regroups transformer that woudl be applied to ipynb files |
|
2 | Module that regroups transformer that woudl be applied to ipynb files | |
3 | before going through the templating machinery. |
|
3 | before going through the templating machinery. | |
4 |
|
4 | |||
5 | It exposes convenient classes to inherit from to access configurability |
|
5 | It exposes convenient classes to inherit from to access configurability | |
6 | as well as decorator to simplify tasks. |
|
6 | as well as decorator to simplify tasks. | |
7 | """ |
|
7 | """ | |
8 |
|
8 | |||
9 | from __future__ import print_function, absolute_import |
|
9 | from __future__ import print_function, absolute_import | |
10 |
|
10 | |||
11 | from IPython.config.configurable import Configurable |
|
11 | from IPython.config.configurable import Configurable | |
12 | from IPython.utils.traitlets import Unicode, Bool, Dict, List |
|
12 | from IPython.utils.traitlets import Unicode, Bool, Dict, List | |
13 |
|
13 | |||
14 | from .config import GlobalConfigurable |
|
14 | from .config import GlobalConfigurable | |
15 |
|
15 | |||
16 | class ConfigurableTransformers(GlobalConfigurable): |
|
16 | class ConfigurableTransformers(GlobalConfigurable): | |
17 | """ A configurable transformer |
|
17 | """ A configurable transformer | |
18 |
|
18 | |||
19 | Inherit from this class if you wish to have configurability for your |
|
19 | Inherit from this class if you wish to have configurability for your | |
20 | transformer. |
|
20 | transformer. | |
21 |
|
21 | |||
22 | Any configurable traitlets this class exposed will be configurable in profiles |
|
22 | Any configurable traitlets this class exposed will be configurable in profiles | |
23 | using c.SubClassName.atribute=value |
|
23 | using c.SubClassName.atribute=value | |
24 |
|
24 | |||
25 | you can overwrite cell_transform to apply a transformation independently on each cell |
|
25 | you can overwrite cell_transform to apply a transformation independently on each cell | |
26 | or __call__ if you prefer your own logic. See orresponding docstring for informations. |
|
26 | or __call__ if you prefer your own logic. See orresponding docstring for informations. | |
27 |
|
27 | |||
28 |
|
28 | |||
29 | """ |
|
29 | """ | |
30 |
|
30 | |||
31 | def __init__(self, config=None, **kw): |
|
31 | def __init__(self, config=None, **kw): | |
32 | super(ConfigurableTransformers, self).__init__(config=config, **kw) |
|
32 | super(ConfigurableTransformers, self).__init__(config=config, **kw) | |
33 |
|
33 | |||
34 | def __call__(self, nb, other): |
|
34 | def __call__(self, nb, other): | |
35 | """transformation to apply on each notebook. |
|
35 | """transformation to apply on each notebook. | |
36 |
|
36 | |||
37 | received a handle to the current notebook as well as a dict of resources |
|
37 | received a handle to the current notebook as well as a dict of resources | |
38 | which structure depends on the transformer. |
|
38 | which structure depends on the transformer. | |
39 |
|
39 | |||
40 | You should return modified nb, other. |
|
40 | You should return modified nb, other. | |
41 |
|
41 | |||
42 | If you wish to apply on each cell, you might want to overwrite cell_transform method. |
|
42 | If you wish to apply on each cell, you might want to overwrite cell_transform method. | |
43 | """ |
|
43 | """ | |
44 | try : |
|
44 | try : | |
45 | for worksheet in nb.worksheets : |
|
45 | for worksheet in nb.worksheets : | |
46 | for index, cell in enumerate(worksheet.cells): |
|
46 | for index, cell in enumerate(worksheet.cells): | |
47 | worksheet.cells[index], other = self.cell_transform(cell, other, 100*index) |
|
47 | worksheet.cells[index], other = self.cell_transform(cell, other, 100*index) | |
48 | return nb, other |
|
48 | return nb, other | |
49 | except NotImplementedError: |
|
49 | except NotImplementedError: | |
50 | raise NotImplementedError('should be implemented by subclass') |
|
50 | raise NotImplementedError('should be implemented by subclass') | |
51 |
|
51 | |||
52 | def cell_transform(self, cell, other, index): |
|
52 | def cell_transform(self, cell, other, index): | |
53 | """ |
|
53 | """ | |
54 | Overwrite if you want to apply a transformation on each cell, |
|
54 | Overwrite if you want to apply a transformation on each cell, | |
55 |
|
55 | |||
56 | receive the current cell, the resource dict and the index of current cell as parameter. |
|
56 | receive the current cell, the resource dict and the index of current cell as parameter. | |
57 |
|
57 | |||
58 | You should return modified cell and resource dict. |
|
58 | You should return modified cell and resource dict. | |
59 | """ |
|
59 | """ | |
|
60 | ||||
60 | raise NotImplementedError('should be implemented by subclass') |
|
61 | raise NotImplementedError('should be implemented by subclass') | |
61 | return cell, other |
|
62 | return cell, other | |
62 |
|
63 | |||
63 | def cell_preprocessor(function): |
|
64 | def cell_preprocessor(function): | |
64 | """ wrap a function to be executed on all cells of a notebook |
|
65 | """ wrap a function to be executed on all cells of a notebook | |
65 |
|
66 | |||
66 | wrapped function parameters : |
|
67 | wrapped function parameters : | |
67 | cell : the cell |
|
68 | cell : the cell | |
68 | other : external resources |
|
69 | other : external resources | |
69 | index : index of the cell |
|
70 | index : index of the cell | |
70 | """ |
|
71 | """ | |
71 | def wrappedfunc(nb, other): |
|
72 | def wrappedfunc(nb, other): | |
72 | for worksheet in nb.worksheets : |
|
73 | for worksheet in nb.worksheets : | |
73 | for index, cell in enumerate(worksheet.cells): |
|
74 | for index, cell in enumerate(worksheet.cells): | |
74 | worksheet.cells[index], other = function(cell, other, index) |
|
75 | worksheet.cells[index], other = function(cell, other, index) | |
75 | return nb, other |
|
76 | return nb, other | |
76 | return wrappedfunc |
|
77 | return wrappedfunc | |
77 |
|
78 | |||
78 |
|
79 | |||
79 | @cell_preprocessor |
|
80 | @cell_preprocessor | |
80 | def haspyout_transformer(cell, other, count): |
|
81 | def haspyout_transformer(cell, other, count): | |
81 | """ |
|
82 | """ | |
82 | Add a haspyout flag to cell that have it |
|
83 | Add a haspyout flag to cell that have it | |
83 |
|
84 | |||
84 | Easier for templating, where you can't know in advance |
|
85 | Easier for templating, where you can't know in advance | |
85 | wether to write the out prompt |
|
86 | wether to write the out prompt | |
86 |
|
87 | |||
87 | """ |
|
88 | """ | |
88 | cell.type = cell.cell_type |
|
89 | cell.type = cell.cell_type | |
89 | cell.haspyout = False |
|
90 | cell.haspyout = False | |
90 | for out in cell.get('outputs', []): |
|
91 | for out in cell.get('outputs', []): | |
91 | if out.output_type == 'pyout': |
|
92 | if out.output_type == 'pyout': | |
92 | cell.haspyout = True |
|
93 | cell.haspyout = True | |
93 | break |
|
94 | break | |
94 | return cell, other |
|
95 | return cell, other | |
95 |
|
96 | |||
96 | @cell_preprocessor |
|
97 | @cell_preprocessor | |
97 | def coalesce_streams(cell, other, count): |
|
98 | def coalesce_streams(cell, other, count): | |
98 | """merge consecutive sequences of stream output into single stream |
|
99 | """merge consecutive sequences of stream output into single stream | |
99 |
|
100 | |||
100 | to prevent extra newlines inserted at flush calls |
|
101 | to prevent extra newlines inserted at flush calls | |
101 |
|
102 | |||
102 | TODO: handle \r deletion |
|
103 | TODO: handle \r deletion | |
103 | """ |
|
104 | """ | |
104 | outputs = cell.get('outputs', []) |
|
105 | outputs = cell.get('outputs', []) | |
105 | if not outputs: |
|
106 | if not outputs: | |
106 | return cell, other |
|
107 | return cell, other | |
107 | new_outputs = [] |
|
108 | new_outputs = [] | |
108 | last = outputs[0] |
|
109 | last = outputs[0] | |
109 | new_outputs = [last] |
|
110 | new_outputs = [last] | |
110 | for output in outputs[1:]: |
|
111 | for output in outputs[1:]: | |
111 | if (output.output_type == 'stream' and |
|
112 | if (output.output_type == 'stream' and | |
112 | last.output_type == 'stream' and |
|
113 | last.output_type == 'stream' and | |
113 | last.stream == output.stream |
|
114 | last.stream == output.stream | |
114 | ): |
|
115 | ): | |
115 | last.text += output.text |
|
116 | last.text += output.text | |
116 | else: |
|
117 | else: | |
117 | new_outputs.append(output) |
|
118 | new_outputs.append(output) | |
118 |
|
119 | |||
119 | cell.outputs = new_outputs |
|
120 | cell.outputs = new_outputs | |
120 | return cell, other |
|
121 | return cell, other |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: modified file chmod 100644 => 100755, file renamed from nbconvert/transformers/reavealhelp.py to nbconvert/transformers/revealhelp.py |
|
NO CONTENT: modified file chmod 100644 => 100755, file renamed from nbconvert/transformers/reavealhelp.py to nbconvert/transformers/revealhelp.py |
1 | NO CONTENT: modified file chmod 100644 => 100755 |
|
NO CONTENT: modified file chmod 100644 => 100755 |
1 | NO CONTENT: file renamed from nbconvert1/converters/lexers.py to nbconvert/utils/lexers.py |
|
NO CONTENT: file renamed from nbconvert1/converters/lexers.py to nbconvert/utils/lexers.py |
General Comments 0
You need to be logged in to leave comments.
Login now