##// END OF EJS Templates
move html header out
Matthias BUSSONNIER -
Show More
@@ -1,230 +1,187 b''
1 """Base classes for the notebook conversion pipeline.
1 """Base classes for the notebook conversion pipeline.
2
2
3 This module defines Converter, from which all objects designed to implement
3 This module defines Converter, from which all objects designed to implement
4 a conversion of IPython notebooks to some other format should inherit.
4 a conversion of IPython notebooks to some other format should inherit.
5 """
5 """
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (c) 2012, the IPython Development Team.
7 # Copyright (c) 2012, 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
17
18 from __future__ import print_function, absolute_import
18 from __future__ import print_function, absolute_import
19 import converters.transformers as trans
19 import converters.transformers as trans
20 from converters.jinja_filters import (python_comment, indent,
20 from converters.jinja_filters import (python_comment, indent,
21 rm_fake, remove_ansi, markdown, highlight,
21 rm_fake, remove_ansi, markdown, highlight,
22 ansi2html, markdown2latex, escape_tex, FilterDataType)
22 ansi2html, markdown2latex, escape_tex, FilterDataType)
23
23
24 from converters.utils import markdown2rst
24 from converters.utils import markdown2rst
25
25
26
26
27
27
28 # Stdlib imports
28 # Stdlib imports
29 import io
29 import io
30 import os
30
31 from IPython.utils import path
32 from IPython.utils.traitlets import MetaHasTraits
31 from IPython.utils.traitlets import MetaHasTraits
33
32
34 from jinja2 import Environment, FileSystemLoader
33 from jinja2 import Environment, FileSystemLoader
35 env = Environment(
34 env = Environment(
36 loader=FileSystemLoader([
35 loader=FileSystemLoader([
37 './templates/',
36 './templates/',
38 './templates/skeleton/',
37 './templates/skeleton/',
39 ]),
38 ]),
40 extensions=['jinja2.ext.loopcontrols']
39 extensions=['jinja2.ext.loopcontrols']
41 )
40 )
42
41
43 texenv = Environment(
42 texenv = Environment(
44 loader=FileSystemLoader([
43 loader=FileSystemLoader([
45 './templates/tex/',
44 './templates/tex/',
46 './templates/skeleton/tex/',
45 './templates/skeleton/tex/',
47 ]),
46 ]),
48 extensions=['jinja2.ext.loopcontrols']
47 extensions=['jinja2.ext.loopcontrols']
49 )
48 )
50
49
51 # IPython imports
50 # IPython imports
52 from IPython.nbformat import current as nbformat
51 from IPython.nbformat import current as nbformat
53 from IPython.config.configurable import Configurable
52 from IPython.config.configurable import Configurable
54 from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
53 from IPython.utils.traitlets import ( Unicode, Any, List, Bool)
55
54
56 #-----------------------------------------------------------------------------
55 #-----------------------------------------------------------------------------
57 # Class declarations
56 # Class declarations
58 #-----------------------------------------------------------------------------
57 #-----------------------------------------------------------------------------
59 class ConversionException(Exception):
58 class ConversionException(Exception):
60 pass
59 pass
61
60
62 #todo move this out
63 def header_body():
64 """Return the body of the header as a list of strings."""
65
66 from pygments.formatters import HtmlFormatter
67
68 header = []
69 static = os.path.join(path.get_ipython_package_dir(),
70 'frontend', 'html', 'notebook', 'static',
71 )
72 here = os.path.split(os.path.realpath(__file__))[0]
73 css = os.path.join(static, 'css')
74 for sheet in [
75 # do we need jquery and prettify?
76 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
77 # 'jquery-ui.min.css'),
78 # os.path.join(static, 'prettify', 'prettify.css'),
79 os.path.join(css, 'boilerplate.css'),
80 os.path.join(css, 'fbm.css'),
81 os.path.join(css, 'notebook.css'),
82 os.path.join(css, 'renderedhtml.css'),
83 os.path.join(css, 'style.min.css'),
84 # our overrides:
85 os.path.join(here, '..', 'css', 'static_html.css'),
86 ]:
87 try:
88 with io.open(sheet, encoding='utf-8') as f:
89 s = f.read()
90 header.append(s)
91 except IOError:
92 # new version of ipython with style.min.css, pass
93 pass
94
95 pygments_css = HtmlFormatter().get_style_defs('.highlight')
96 header.append(pygments_css)
97 return header
98
99
100
101
102
103 inlining = {}
104 inlining['css'] = header_body()
105
106
61
107
62
108 texenv.block_start_string = '((*'
63 texenv.block_start_string = '((*'
109 texenv.block_end_string = '*))'
64 texenv.block_end_string = '*))'
110
65
111 texenv.variable_start_string = '((('
66 texenv.variable_start_string = '((('
112 texenv.variable_end_string = ')))'
67 texenv.variable_end_string = ')))'
113
68
114 texenv.comment_start_string = '((='
69 texenv.comment_start_string = '((='
115 texenv.comment_end_string = '=))'
70 texenv.comment_end_string = '=))'
116
71
117 texenv.filters['escape_tex'] = escape_tex
72 texenv.filters['escape_tex'] = escape_tex
118
73
119
74
120 class ConverterTemplate(Configurable):
75 class ConverterTemplate(Configurable):
121 """ A Jinja2 base converter templates
76 """ A Jinja2 base converter templates
122
77
123 Preprocess the ipynb files, feed it throug jinja templates,
78 Preprocess the ipynb files, feed it throug jinja templates,
124 and spit an converted files and a data object with other data
79 and spit an converted files and a data object with other data
125
80
126 shoudl be mostly configurable
81 shoudl be mostly configurable
127 """
82 """
128
83
129 pre_transformer_order = List(['haspyout_transformer'],
84 pre_transformer_order = List(['haspyout_transformer'],
130 config=True,
85 config=True,
131 help= """
86 help= """
132 An ordered list of pre transformer to apply to the ipynb
87 An ordered list of pre transformer to apply to the ipynb
133 file befor running through templates
88 file befor running through templates
134 """
89 """
135 )
90 )
136
91
137 tex_environement = Bool(False,
92 tex_environement = Bool(False,
138 config=True,
93 config=True,
139 help=""" is this a tex environment or not """)
94 help=""" is this a tex environment or not """)
140
95
141 template_file = Unicode('',
96 template_file = Unicode('',
142 config=True,
97 config=True,
143 help=""" Name of the template file to use """ )
98 help=""" Name of the template file to use """ )
144 #-------------------------------------------------------------------------
99 #-------------------------------------------------------------------------
145 # Instance-level attributes that are set in the constructor for this
100 # Instance-level attributes that are set in the constructor for this
146 # class.
101 # class.
147 #-------------------------------------------------------------------------
102 #-------------------------------------------------------------------------
148
103
149
104
150 preprocessors = []
105 preprocessors = []
151
106
152 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
107 def __init__(self, preprocessors={}, jinja_filters={}, config=None, **kw):
153 """ Init a new converter.
108 """ Init a new converter.
154
109
155
110
156 config: the Configurable confgg object to pass around
111 config: the Configurable confgg object to pass around
157
112
158 preprocessors: dict of **availlable** key/value function to run on
113 preprocessors: dict of **availlable** key/value function to run on
159 ipynb json data before conversion to extract/inline file,
114 ipynb json data before conversion to extract/inline file,
160
115
161 jinja_filter : dict of supplementary jinja filter that should be made
116 jinja_filter : dict of supplementary jinja filter that should be made
162 availlable in template. If those are of Configurable Class type, they
117 availlable in template. If those are of Configurable Class type, they
163 will be instanciated with the config object as argument.
118 will be instanciated with the config object as argument.
164
119
165 """
120 """
166 super(ConverterTemplate, self).__init__(config=config, **kw)
121 super(ConverterTemplate, self).__init__(config=config, **kw)
167 self.env = texenv if self.tex_environement else env
122 self.env = texenv if self.tex_environement else env
168 self.ext = '.tplx' if self.tex_environement else '.tpl'
123 self.ext = '.tplx' if self.tex_environement else '.tpl'
169
124
170 for name in self.pre_transformer_order:
125 for name in self.pre_transformer_order:
171 transformer = getattr(preprocessors, name, getattr(trans, name, None))
126 transformer = getattr(preprocessors, name, getattr(trans, name, None))
172 if isinstance(transformer, MetaHasTraits):
127 if isinstance(transformer, MetaHasTraits):
173 transformer = transformer(config=config)
128 transformer = transformer(config=config)
174 self.preprocessors.append(transformer)
129 self.preprocessors.append(transformer)
175
130
176 ## for compat, remove later
131 ## for compat, remove later
177 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
132 self.preprocessors.append(trans.ExtractFigureTransformer(config=config))
178 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
133 self.preprocessors.append(trans.RevealHelpTransformer(config=config))
134 self.preprocessors.append(trans.CSSHtmlHeaderTransformer(config=config))
179
135
180 ##
136 ##
181 self.env.filters['filter_data_type'] = FilterDataType(config=config)
137 self.env.filters['filter_data_type'] = FilterDataType(config=config)
182 self.env.filters['pycomment'] = python_comment
138 self.env.filters['pycomment'] = python_comment
183 self.env.filters['indent'] = indent
139 self.env.filters['indent'] = indent
184 self.env.filters['rm_fake'] = rm_fake
140 self.env.filters['rm_fake'] = rm_fake
185 self.env.filters['rm_ansi'] = remove_ansi
141 self.env.filters['rm_ansi'] = remove_ansi
186 self.env.filters['markdown'] = markdown
142 self.env.filters['markdown'] = markdown
187 self.env.filters['highlight'] = highlight
143 self.env.filters['highlight'] = highlight
188 self.env.filters['ansi2html'] = ansi2html
144 self.env.filters['ansi2html'] = ansi2html
189 self.env.filters['markdown2latex'] = markdown2latex
145 self.env.filters['markdown2latex'] = markdown2latex
190 self.env.filters['markdown2rst'] = markdown2rst
146 self.env.filters['markdown2rst'] = markdown2rst
191 for key, filtr in jinja_filters.iteritems():
147 for key, filtr in jinja_filters.iteritems():
192 if isinstance(filtr, MetaHasTraits):
148 if isinstance(filtr, MetaHasTraits):
193 self.env.filters[key] = filtr(config=config)
149 self.env.filters[key] = filtr(config=config)
194 else :
150 else :
195 self.env.filters[key] = filtr
151 self.env.filters[key] = filtr
196
152
197 self.template = self.env.get_template(self.template_file+self.ext)
153 self.template = self.env.get_template(self.template_file+self.ext)
198
154
199
155
200 def process(self, nb):
156 def process(self, nb):
201 """
157 """
202 preprocess the notebook json for easier use with the templates.
158 preprocess the notebook json for easier use with the templates.
203 will call all the `preprocessor`s in order before returning it.
159 will call all the `preprocessor`s in order before returning it.
204 """
160 """
205
161
206 # dict of 'resources' that could be made by the preprocessors
162 # dict of 'resources' that could be made by the preprocessors
207 # like key/value data to extract files from ipynb like in latex conversion
163 # like key/value data to extract files from ipynb like in latex conversion
208 resources = {}
164 resources = {}
209
165
210 for preprocessor in self.preprocessors:
166 for preprocessor in self.preprocessors:
211 nb, resources = preprocessor(nb, resources)
167 nb, resources = preprocessor(nb, resources)
212
168
213 return nb, resources
169 return nb, resources
214
170
215 def convert(self, nb):
171 def convert(self, nb):
216 """ convert the ipynb file
172 """ convert the ipynb file
217
173
218 return both the converted ipynb file and a dict containing potential
174 return both the converted ipynb file and a dict containing potential
219 other resources
175 other resources
220 """
176 """
221 nb, resources = self.process(nb)
177 nb, resources = self.process(nb)
222 return self.template.render(nb=nb, inlining=inlining), resources
178 return self.template.render(nb=nb, resources=resources), resources
223
179
224
180
225 def from_filename(self, filename):
181 def from_filename(self, filename):
226 "read and parse notebook into NotebookNode called self.nb"
182 "read and parse notebook into NotebookNode called self.nb"
227 with io.open(filename) as f:
183 with io.open(filename) as f:
228 return self.convert(nbformat.read(f, 'json'))
184 return self.convert(nbformat.read(f, 'json'))
229
185
230
186
187
@@ -1,225 +1,293 b''
1 """
1 """
2
2
3 """
3 """
4
4
5 from __future__ import print_function, absolute_import
5 from __future__ import print_function
6
6
7
7 from IPython.config.configurable import Configurable
8 from IPython.config.configurable import Configurable
8 from IPython.utils.traitlets import Unicode, Bool, Dict, List
9 from IPython.utils.traitlets import Unicode, Bool, Dict, List
9 from .jinja_filters import GlobalConfigurable
10
10
11 class ConfigurableTransformers(GlobalConfigurable):
11 class ConfigurableTransformers(Configurable):
12 """ A configurable transformer """
12 """ A configurable transformer """
13
13
14 def __init__(self, config=None, **kw):
14 def __init__(self, config=None, **kw):
15 super(ConfigurableTransformers, self).__init__(config=config, **kw)
15 super(ConfigurableTransformers, self).__init__(config=config, **kw)
16
16
17 def __call__(self, nb, other):
17 def __call__(self, nb, other):
18 try :
18 try :
19 for worksheet in nb.worksheets :
19 for worksheet in nb.worksheets :
20 for index, cell in enumerate(worksheet.cells):
20 for index, cell in enumerate(worksheet.cells):
21 worksheet.cells[index], other = self.cell_transform(cell, other, index)
21 worksheet.cells[index], other = self.cell_transform(cell, other, index)
22 return nb, other
22 return nb, other
23 except NotImplementedError as error :
23 except NotImplementedError as error :
24 raise NotImplementedError('should be implemented by subclass')
24 raise NotImplementedError('should be implemented by subclass')
25
25
26 def cell_transform(self, cell, other, index):
26 def cell_transform(self, cell, other, index):
27 """
27 """
28 Overwrite if you want to apply a transformation on each cell
28 Overwrite if you want to apply a transformation on each cell
29 """
29 """
30 raise NotImplementedError('should be implemented by subclass')
30 raise NotImplementedError('should be implemented by subclass')
31
31
32
32
33 class ActivatableTransformer(ConfigurableTransformers):
33 class ActivatableTransformer(ConfigurableTransformers):
34
34
35 enabled = Bool(False, config=True)
35 enabled = Bool(False, config=True)
36
36
37 def __call__(self, nb, other):
37 def __call__(self, nb, other):
38 if not self.enabled :
38 if not self.enabled :
39 return nb,other
39 return nb,other
40 else :
40 else :
41 return super(ActivatableTransformer,self).__call__(nb, other)
41 return super(ActivatableTransformer,self).__call__(nb, other)
42
42
43
43
44 def cell_preprocessor(function):
44 def cell_preprocessor(function):
45 """ wrap a function to be executed on all cells of a notebook
45 """ wrap a function to be executed on all cells of a notebook
46
46
47 wrapped function parameters :
47 wrapped function parameters :
48 cell : the cell
48 cell : the cell
49 other : external resources
49 other : external resources
50 index : index of the cell
50 index : index of the cell
51 """
51 """
52 def wrappedfunc(nb, other):
52 def wrappedfunc(nb, other):
53 for worksheet in nb.worksheets :
53 for worksheet in nb.worksheets :
54 for index, cell in enumerate(worksheet.cells):
54 for index, cell in enumerate(worksheet.cells):
55 worksheet.cells[index], other = function(cell, other, index)
55 worksheet.cells[index], other = function(cell, other, index)
56 return nb, other
56 return nb, other
57 return wrappedfunc
57 return wrappedfunc
58
58
59
59
60 @cell_preprocessor
60 @cell_preprocessor
61 def haspyout_transformer(cell, other, count):
61 def haspyout_transformer(cell, other, count):
62 """
62 """
63 Add a haspyout flag to cell that have it
63 Add a haspyout flag to cell that have it
64
64
65 Easier for templating, where you can't know in advance
65 Easier for templating, where you can't know in advance
66 wether to write the out prompt
66 wether to write the out prompt
67
67
68 """
68 """
69 cell.type = cell.cell_type
69 cell.type = cell.cell_type
70 cell.haspyout = False
70 cell.haspyout = False
71 for out in cell.get('outputs', []):
71 for out in cell.get('outputs', []):
72 if out.output_type == 'pyout':
72 if out.output_type == 'pyout':
73 cell.haspyout = True
73 cell.haspyout = True
74 break
74 break
75 return cell, other
75 return cell, other
76
76
77
77
78 # todo, make the key part configurable.
78 # todo, make the key part configurable.
79
79
80 class ExtractFigureTransformer(ActivatableTransformer):
80 class ExtractFigureTransformer(ActivatableTransformer):
81
81
82 extra_ext_map = Dict({},
82 extra_ext_map = Dict({},
83 config=True,
83 config=True,
84 help="""extra map to override extension based on type.
84 help="""extra map to override extension based on type.
85 Usefull for latex where svg will be converted to pdf before inclusion
85 Usefull for latex where svg will be converted to pdf before inclusion
86 """
86 """
87 )
87 )
88 display_data_priority = List(['html', 'pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
89 config=True,
90 help= """
91 An ordered list of prefered output type, the first
92 encounterd will usually be used when converting discarding
93 the others.
94 """
95 )
96
88
97
89 #to do change this to .format {} syntax
98 #to do change this to .format {} syntax
90 key_tpl = Unicode('_fig_%02i.%s', config=True)
99 key_tpl = Unicode('_fig_%02i.%s', config=True)
91
100
92 def _get_ext(self, ext):
101 def _get_ext(self, ext):
93 if ext in self.extra_ext_map :
102 if ext in self.extra_ext_map :
94 return self.extra_ext_map[ext]
103 return self.extra_ext_map[ext]
95 return ext
104 return ext
96
105
97 def _new_figure(self, data, fmt, count):
106 def _new_figure(self, data, fmt, count):
98 """Create a new figure file in the given format.
107 """Create a new figure file in the given format.
99
108
100 Returns a path relative to the input file.
109 Returns a path relative to the input file.
101 """
110 """
102 figname = self.key_tpl % (count, self._get_ext(fmt))
111 figname = self.key_tpl % (count, self._get_ext(fmt))
103 key = self.key_tpl % (count, fmt)
112 key = self.key_tpl % (count, fmt)
104
113
105 # Binary files are base64-encoded, SVG is already XML
114 # Binary files are base64-encoded, SVG is already XML
106 if fmt in ('png', 'jpg', 'pdf'):
115 if fmt in ('png', 'jpg', 'pdf'):
107 data = data.decode('base64')
116 data = data.decode('base64')
108
117
109 return figname, key, data
118 return figname, key, data
110
119
111
120
112 def cell_transform(self, cell, other, count):
121 def cell_transform(self, cell, other, count):
113 if other.get('figures',None) is None :
122 if other.get('figures',None) is None :
114 other['figures']={}
123 other['figures']={}
115 for i, out in enumerate(cell.get('outputs', [])):
124 for i, out in enumerate(cell.get('outputs', [])):
116 for type in self.display_data_priority:
125 for type in self.display_data_priority:
117 if out.hasattr(type):
126 if out.hasattr(type):
118 figname, key, data = self._new_figure(out[type], type, count)
127 figname, key, data = self._new_figure(out[type], type, count)
119 out['key_'+type] = figname
128 out['key_'+type] = figname
120 other['figures'][key] = data
129 other['figures'][key] = data
121 count = count+1
130 count = count+1
122 return cell, other
131 return cell, other
123
132
124 class RevealHelpTransformer(ConfigurableTransformers):
133 class RevealHelpTransformer(ConfigurableTransformers):
125
134
126 section_open = False
135 section_open = False
127 subsection_open = False
136 subsection_open = False
128 fragment_open = False
137 fragment_open = False
129
138
130 def open_subsection(self):
139 def open_subsection(self):
131 self.subsection_open = True
140 self.subsection_open = True
132 return True
141 return True
133
142
134 def open_section(self):
143 def open_section(self):
135 self.section_open = True
144 self.section_open = True
136 return True
145 return True
137
146
138 def open_fragment(self):
147 def open_fragment(self):
139 self.fragment_open = True
148 self.fragment_open = True
140 return True
149 return True
141
150
142 # could probaly write those maybe_close/open
151 # could probaly write those maybe_close/open
143 # with a function functor
152 # with a function functor
144 def maybe_close_section(self):
153 def maybe_close_section(self):
145 """return True is already open, false otherwise
154 """return True is already open, false otherwise
146 and change state to close
155 and change state to close
147 """
156 """
148 if self.section_open :
157 if self.section_open :
149 self.section_open = False
158 self.section_open = False
150 return True
159 return True
151 else :
160 else :
152 return False
161 return False
153
162
154 def maybe_open_section(self):
163 def maybe_open_section(self):
155 """return True is already open, false otherwise
164 """return True is already open, false otherwise
156 and change state to close
165 and change state to close
157 """
166 """
158 if not self.section_open :
167 if not self.section_open :
159 self.section_open = True
168 self.section_open = True
160 return True
169 return True
161 else :
170 else :
162 return False
171 return False
163
172
164 def maybe_open_subsection(self):
173 def maybe_open_subsection(self):
165 """return True is already open, false otherwise
174 """return True is already open, false otherwise
166 and change state to close
175 and change state to close
167 """
176 """
168 if not self.subsection_open :
177 if not self.subsection_open :
169 self.subsection_open = True
178 self.subsection_open = True
170 return True
179 return True
171 else :
180 else :
172 return False
181 return False
173
182
174 def maybe_close_subsection(self):
183 def maybe_close_subsection(self):
175 """return True is already open, false otherwise
184 """return True is already open, false otherwise
176 and change state to close
185 and change state to close
177 """
186 """
178 if self.subsection_open :
187 if self.subsection_open :
179 self.subsection_open = False
188 self.subsection_open = False
180 return True
189 return True
181 else :
190 else :
182 return False
191 return False
183
192
184 def maybe_close_fragment(self):
193 def maybe_close_fragment(self):
185 """return True is already open, false otherwise
194 """return True is already open, false otherwise
186 and change state to close
195 and change state to close
187 """
196 """
188 if self.fragment_open :
197 if self.fragment_open :
189 self.fragment_open = False
198 self.fragment_open = False
190 return True
199 return True
191 else :
200 else :
192 return False
201 return False
193
202
194 def cell_transform(self, cell, other,count):
203 def cell_transform(self, cell, other,count):
195 ctype = cell.metadata.get('slideshow',{}).get('slide_type',None)
204 ctype = cell.metadata.get('slideshow',{}).get('slide_type',None)
196 if ctype in [None, '-'] :
205 if ctype in [None, '-'] :
197 cell.metadata.slideshow = {}
206 cell.metadata.slideshow = {}
198 cell.metadata.slideshow['slide_type'] = None
207 cell.metadata.slideshow['slide_type'] = None
199 elif ctype == 'fragment':
208 elif ctype == 'fragment':
200 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
209 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
201 cell.metadata.slideshow.close_subsection = False
210 cell.metadata.slideshow.close_subsection = False
202 cell.metadata.slideshow.close_section = False
211 cell.metadata.slideshow.close_section = False
203
212
204 cell.metadata.slideshow.open_section = self.maybe_open_section()
213 cell.metadata.slideshow.open_section = self.maybe_open_section()
205 cell.metadata.slideshow.open_subsection = self.maybe_open_subsection()
214 cell.metadata.slideshow.open_subsection = self.maybe_open_subsection()
206 cell.metadata.slideshow.open_fragment = self.open_fragment()
215 cell.metadata.slideshow.open_fragment = self.open_fragment()
207
216
208 elif ctype == 'subslide':
217 elif ctype == 'subslide':
209 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
218 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
210 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
219 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
211 cell.metadata.slideshow.close_section = False
220 cell.metadata.slideshow.close_section = False
212
221
213 cell.metadata.slideshow.open_section = self.maybe_open_section()
222 cell.metadata.slideshow.open_section = self.maybe_open_section()
214 cell.metadata.slideshow.open_subsection = self.open_subsection()
223 cell.metadata.slideshow.open_subsection = self.open_subsection()
215 cell.metadata.slideshow.open_fragment = False
224 cell.metadata.slideshow.open_fragment = False
216 elif ctype == 'slide':
225 elif ctype == 'slide':
217 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
226 cell.metadata.slideshow.close_fragment = self.maybe_close_fragment()
218 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
227 cell.metadata.slideshow.close_subsection = self.maybe_close_subsection()
219 cell.metadata.slideshow.close_section = self.maybe_close_section()
228 cell.metadata.slideshow.close_section = self.maybe_close_section()
220
229
221 cell.metadata.slideshow.open_section = self.open_section()
230 cell.metadata.slideshow.open_section = self.open_section()
222 cell.metadata.slideshow.open_subsection = self.open_subsection()
231 cell.metadata.slideshow.open_subsection = self.open_subsection()
223 cell.metadata.slideshow.open_fragment = False
232 cell.metadata.slideshow.open_fragment = False
224 return cell,other
233 return cell,other
225
234
235
236 class CSSHtmlHeaderTransformer(ActivatableTransformer):
237
238 def __call__(self, nb, resources):
239 """Fetch and add css to the resource dict
240
241 Fetch css from IPython adn Pygment to add at the beginning
242 of the html files.
243
244 Add this css in resources in the "inlining.css" key
245 """
246 resources['inlining']= {}
247 resources['inlining']['css'] = self.header
248 return nb, resources
249
250 header= []
251
252 def __init__(self, config=None, **kw):
253 super(CSSHtmlHeaderTransformer,self).__init__(config=config, **kw)
254 if self.enabled :
255 self.regen_header()
256
257 def regen_header(self):
258 ## lazy load asa this might not be use in many transformers
259 import os
260 from IPython.utils import path
261 import io
262 from pygments.formatters import HtmlFormatter
263 header = []
264 static = os.path.join(path.get_ipython_package_dir(),
265 'frontend', 'html', 'notebook', 'static',
266 )
267 here = os.path.split(os.path.realpath(__file__))[0]
268 css = os.path.join(static, 'css')
269 for sheet in [
270 # do we need jquery and prettify?
271 # os.path.join(static, 'jquery', 'css', 'themes', 'base',
272 # 'jquery-ui.min.css'),
273 # os.path.join(static, 'prettify', 'prettify.css'),
274 os.path.join(css, 'boilerplate.css'),
275 os.path.join(css, 'fbm.css'),
276 os.path.join(css, 'notebook.css'),
277 os.path.join(css, 'renderedhtml.css'),
278 os.path.join(css, 'style.min.css'),
279 # our overrides:
280 os.path.join(here, '..', 'css', 'static_html.css'),
281 ]:
282 try:
283 with io.open(sheet, encoding='utf-8') as f:
284 s = f.read()
285 header.append(s)
286 except IOError:
287 # new version of ipython with style.min.css, pass
288 pass
289
290 pygments_css = HtmlFormatter().get_style_defs('.highlight')
291 header.append(pygments_css)
292 self.header = header
293
@@ -1,10 +1,11 b''
1 c = get_config()
1 c = get_config()
2
2
3
3
4 c.ConverterTemplate.extract_figures=False
4 c.ConverterTemplate.extract_figures=False
5 c.ConverterTemplate.template_file='basichtml'
5 c.ConverterTemplate.template_file='basichtml'
6 c.ConverterTemplate.tex_environement=False
6 c.ConverterTemplate.tex_environement=False
7
7
8 c.NbconvertApp.fileext='html'
8 c.NbconvertApp.fileext='html'
9
9
10 c.ExtractFigureTransformer.enabled = False
10 c.ExtractFigureTransformer.enabled = False
11 c.CSSHtmlHeaderTransformer.enabled=True
@@ -1,9 +1,5 b''
1 c = get_config()
1 c = get_config()
2
2 load_subconfig('base_html.nbcv')
3
3
4 c.ConverterTemplate.template_file='fullhtml'
4 c.ConverterTemplate.template_file='fullhtml'
5 c.ConverterTemplate.tex_environement=False
6
7 c.NbconvertApp.fileext='html'
8
5
9 c.ExtractFigureTransformer.enabled = False
@@ -1,46 +1,46 b''
1 {%- extends 'basichtml.tpl' -%}
1 {%- extends 'basichtml.tpl' -%}
2
2
3 {%- block header -%}<!DOCTYPE html>
3 {%- block header -%}<!DOCTYPE html>
4 <html>
4 <html>
5 <head>
5 <head>
6 <meta charset="UTF-8">
6 <meta charset="UTF-8">
7 <title>[{{nb.metadata.name}}]</title>
7 <title>[{{nb.metadata.name}}]</title>
8 {% for css in inlining.css -%}
8 {% for css in resources.inlining.css -%}
9 <style type="text/css">
9 <style type="text/css">
10 {{css}}
10 {{css}}
11 </style>
11 </style>
12 {% endfor %}
12 {% endfor %}
13 <script src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" type="text/javascript">
13 <script src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" type="text/javascript">
14
14
15 </script>
15 </script>
16 <script type="text/javascript">
16 <script type="text/javascript">
17 init_mathjax = function() {
17 init_mathjax = function() {
18 if (window.MathJax) {
18 if (window.MathJax) {
19 // MathJax loaded
19 // MathJax loaded
20 MathJax.Hub.Config({
20 MathJax.Hub.Config({
21 tex2jax: {
21 tex2jax: {
22 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
22 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
23 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
23 displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
24 },
24 },
25 displayAlign: 'left', // Change this to 'center' to center equations.
25 displayAlign: 'left', // Change this to 'center' to center equations.
26 "HTML-CSS": {
26 "HTML-CSS": {
27 styles: {'.MathJax_Display': {"margin": 0}}
27 styles: {'.MathJax_Display': {"margin": 0}}
28 }
28 }
29 });
29 });
30 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
30 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
31 }
31 }
32 }
32 }
33 init_mathjax();
33 init_mathjax();
34 </script>
34 </script>
35 </head>
35 </head>
36 {%- endblock header -%}
36 {%- endblock header -%}
37
37
38
38
39 {% block body %}
39 {% block body %}
40 <body>{{ super() }}
40 <body>{{ super() }}
41 </body>
41 </body>
42 {%- endblock body %}
42 {%- endblock body %}
43
43
44
44
45 {% block footer %}
45 {% block footer %}
46 </html>{% endblock footer %}
46 </html>{% endblock footer %}
@@ -1,150 +1,150 b''
1 {%- extends 'basichtml.tpl' -%}
1 {%- extends 'basichtml.tpl' -%}
2
2
3
3
4 {% block any_cell -%}
4 {% block any_cell -%}
5
5
6 {% if cell.metadata.slideshow.close_fragment %}
6 {% if cell.metadata.slideshow.close_fragment %}
7 </div>
7 </div>
8 {% endif %}
8 {% endif %}
9 {% if cell.metadata.slideshow.close_subsection %}
9 {% if cell.metadata.slideshow.close_subsection %}
10 </section>
10 </section>
11 {% endif %}
11 {% endif %}
12 {% if cell.metadata.slideshow.close_section %}
12 {% if cell.metadata.slideshow.close_section %}
13 </section>
13 </section>
14 {% endif %}
14 {% endif %}
15
15
16 {% if cell.metadata.slideshow.open_section %}
16 {% if cell.metadata.slideshow.open_section %}
17 <section>
17 <section>
18 {%- endif %}
18 {%- endif %}
19 {% if cell.metadata.slideshow.open_subsection %}
19 {% if cell.metadata.slideshow.open_subsection %}
20 <section>
20 <section>
21 {%- endif %}
21 {%- endif %}
22 {% if cell.metadata.slideshow.open_fragment %}
22 {% if cell.metadata.slideshow.open_fragment %}
23 <div class='fragment'>
23 <div class='fragment'>
24 {% endif %}
24 {% endif %}
25 {% if cell.metadata.slideshow.slide_type in ['notes'] %}
25 {% if cell.metadata.slideshow.slide_type in ['notes'] %}
26 <aside class="notes">
26 <aside class="notes">
27 {{ super() }}
27 {{ super() }}
28 </aside>
28 </aside>
29 {% elif cell.metadata.slideshow.slide_type not in ['skip'] %}
29 {% elif cell.metadata.slideshow.slide_type not in ['skip'] %}
30 {{ super() }}
30 {{ super() }}
31 {% endif %}
31 {% endif %}
32
32
33 {% endblock %}
33 {% endblock %}
34
34
35
35
36 {% block body %}
36 {% block body %}
37 <body>
37 <body>
38 <div class="reveal"><div class="slides">
38 <div class="reveal"><div class="slides">
39 {{ super() }}
39 {{ super() }}
40 </section>
40 </section>
41 </section>
41 </section>
42 </div></div>
42 </div></div>
43
43
44 <script src="reveal/lib/js/head.min.js"></script>
44 <script src="reveal/lib/js/head.min.js"></script>
45
45
46 <script src="reveal/js/reveal.min.js"></script>
46 <script src="reveal/js/reveal.min.js"></script>
47
47
48 <script>
48 <script>
49
49
50 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
50 // Full list of configuration options available here: https://github.com/hakimel/reveal.js#configuration
51 Reveal.initialize({
51 Reveal.initialize({
52 controls: true,
52 controls: true,
53 progress: true,
53 progress: true,
54 history: true,
54 history: true,
55
55
56 theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
56 theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
57 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
57 transition: Reveal.getQueryHash().transition || 'linear', // default/cube/page/concave/zoom/linear/none
58
58
59 // Optional libraries used to extend on reveal.js
59 // Optional libraries used to extend on reveal.js
60 dependencies: [
60 dependencies: [
61 { src: 'reveal/lib/js/classList.js', condition: function() { return !document.body.classList; } },
61 { src: 'reveal/lib/js/classList.js', condition: function() { return !document.body.classList; } },
62 { src: 'reveal/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
62 { src: 'reveal/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
63 { src: 'reveal/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
63 { src: 'reveal/plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
64 { src: 'notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
64 { src: 'notes/notes.js', async: true, condition: function() { return !!document.body.classList; } },
65 { src: 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML', async: true },
65 { src: 'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS_HTML', async: true },
66 { src: 'js/revealmathjax.js', async: true}
66 { src: 'js/revealmathjax.js', async: true}
67 ]
67 ]
68 });
68 });
69 </script>
69 </script>
70
70
71 <script>
71 <script>
72 Reveal.addEventListener( 'slidechanged', function( event ) {
72 Reveal.addEventListener( 'slidechanged', function( event ) {
73 MathJax.Hub.Rerender(event.currentSlide);
73 MathJax.Hub.Rerender(event.currentSlide);
74 });
74 });
75 </script>
75 </script>
76 </body>
76 </body>
77 </html>{% endblock body %}
77 </html>{% endblock body %}
78
78
79
79
80
80
81
81
82 {% block header %}<!DOCTYPE html>
82 {% block header %}<!DOCTYPE html>
83 <html>
83 <html>
84 <head>
84 <head>
85
85
86 <meta charset="utf-8" />
86 <meta charset="utf-8" />
87 <meta http-equiv="X-UA-Compatible" content="chrome=1">
87 <meta http-equiv="X-UA-Compatible" content="chrome=1">
88
88
89 <meta name="apple-mobile-web-app-capable" content="yes" />
89 <meta name="apple-mobile-web-app-capable" content="yes" />
90 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
90 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
91
91
92 <link rel="stylesheet" href="reveal/css/reveal.css">
92 <link rel="stylesheet" href="reveal/css/reveal.css">
93 <link rel="stylesheet" href="reveal/css/theme/simple.css" id="theme">
93 <link rel="stylesheet" href="reveal/css/theme/simple.css" id="theme">
94
94
95 <!-- For syntax highlighting -->
95 <!-- For syntax highlighting -->
96 <link rel="stylesheet" href="reveal/lib/css/zenburn.css">
96 <link rel="stylesheet" href="reveal/lib/css/zenburn.css">
97
97
98 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
98 <!-- If the query includes 'print-pdf', use the PDF print sheet -->
99 <script>
99 <script>
100 document.write( '<link rel="stylesheet" href="reveal/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
100 document.write( '<link rel="stylesheet" href="reveal/css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
101 </script>
101 </script>
102
102
103 <!--[if lt IE 9]>
103 <!--[if lt IE 9]>
104 <script src="reveal/lib/js/html5shiv.js"></script>
104 <script src="reveal/lib/js/html5shiv.js"></script>
105 <![endif]-->
105 <![endif]-->
106
106
107 {% for css in inlining.css -%}
107 {% for css in resources.inlining.css -%}
108 <style type="text/css">
108 <style type="text/css">
109 {{css}}
109 {{css}}
110 </style>
110 </style>
111 {% endfor %}
111 {% endfor %}
112
112
113 <style type="text/css">
113 <style type="text/css">
114 /* Overrides of notebook CSS for static HTML export */
114 /* Overrides of notebook CSS for static HTML export */
115
115
116 .reveal {
116 .reveal {
117 font-size: 20px;
117 font-size: 20px;
118 }
118 }
119 .reveal pre {
119 .reveal pre {
120 width: 100%;
120 width: 100%;
121 padding: 0.2em;
121 padding: 0.2em;
122 margin: 0px auto;
122 margin: 0px auto;
123 font-family: monospace, sans-serif;
123 font-family: monospace, sans-serif;
124 font-size: 60%;
124 font-size: 60%;
125 box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
125 box-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
126 }
126 }
127 .reveal section img {
127 .reveal section img {
128 border: 0px solid black;
128 border: 0px solid black;
129 box-shadow: 0 0 10px rgba(0, 0, 0, 0);
129 box-shadow: 0 0 10px rgba(0, 0, 0, 0);
130 }
130 }
131 div.input_area {
131 div.input_area {
132 padding: 0.2em;
132 padding: 0.2em;
133 }
133 }
134 div.code_cell {
134 div.code_cell {
135 background-color: transparent;
135 background-color: transparent;
136 }
136 }
137 div.prompt {
137 div.prompt {
138 width: 11ex;
138 width: 11ex;
139 padding: 0.0em;
139 padding: 0.0em;
140 margin: 0px;
140 margin: 0px;
141 font-family: monospace;
141 font-family: monospace;
142 font-size: 60%;
142 font-size: 60%;
143 text-align: center;
143 text-align: center;
144 }
144 }
145 div.output_prompt {
145 div.output_prompt {
146 /* 5px right shift to account for margin in parent container */
146 /* 5px right shift to account for margin in parent container */
147 margin: 5px 5px 0 -5px;
147 margin: 5px 5px 0 -5px;
148 }
148 }
149 </style>
149 </style>
150 </head>{% endblock %}
150 </head>{% endblock %}
General Comments 0
You need to be logged in to leave comments. Login now