def get_html_from_filepath(filepath, start=0, end=None, preprocessors=[], template=None): """Return the HTML from a Jupyter Notebook """ template_file = 'basic' extra_loaders = [] if template: extra_loaders.append(jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) config = get_config() config.update({'CSSHTMLHeaderTransformer': { 'enabled': True, 'highlight_class': '.highlight-ipynb'}, 'SubCell': { 'enabled':True, 'start':start, 'end':end}}) exporter = HTMLExporter(config=config, template_file=template_file, extra_loaders=extra_loaders, filters={'highlight2html': custom_highlighter}, preprocessors=[SubCell] + preprocessors) config.CSSHTMLHeaderPreprocessor.highlight_class = " .highlight pre " content, info = exporter.from_filename(filepath) return content, info
def get_html_from_filepath(filepath, start=0, end=None): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({ 'CSSHTMLHeaderTransformer': { 'enabled': True, 'highlight_class': '.highlight-ipynb' }, 'SubCell': { 'enabled': True, 'start': start, 'end': end } }) exporter = HTMLExporter(config=config, template_file='basic', filters={'highlight2html': custom_highlighter}, preprocessors=[SubCell]) content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content, 'html.parser') for i in soup.findAll('div', {'class': 'input'}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup.decode(formatter=None) return content, info
def get_html_from_filepath(filepath): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config( { "CSSHTMLHeaderTransformer": { "enabled": True, "highlight_class": ".highlight-ipynb", }, } ) config.HTMLExporter.preprocessors = [HtmlLinksPreprocessor] config.HTMLExporter.exclude_input = True config.HTMLExporter.exclude_output_prompt = True config.HtmlLinksPreprocessor["enabled"] = True path = os.path.dirname(os.path.realpath(__file__)) exporter = HTMLExporter( config=config, template_file="no_code", template_path=[".", path + "/../../../scripts/"], filters={"highlight2html": custom_highlighter}, ) content, info = exporter.from_filename(filepath) return content, info
def convert_ipynb_to_html(notebook_file, html_file): """ Convert the given Jupyter notebook file (``.ipynb``) to HTML and write it out as the given ``.html`` file. Parameters ---------- notebook_file : str Path to input Jupyter notebook file. html_file : str Path to output HTML file. Note ---- This function is also exposed as the :ref:`render_notebook <render_notebook>` command-line utility. """ # set a high timeout for datasets with a large number of features report_config = Config({ 'ExecutePreprocessor': { 'enabled': True, 'timeout': 3600 }, 'HTMLExporter': { 'template_path': [template_path], 'template_file': 'report.tpl' } }) exportHtml = HTMLExporter(config=report_config) output, _ = exportHtml.from_filename(notebook_file) open(html_file, mode='w', encoding='utf-8').write(output)
def _process(self): config = Config() config.HTMLExporter.preprocessors = [CppHighlighter] config.HTMLExporter.template_file = 'basic' with self.attachment.file.open() as f: notebook = nbformat.read(f, as_version=4) html_exporter = HTMLExporter(config=config) body, resources = html_exporter.from_notebook_node(notebook) css_code = '\n'.join(resources['inlining'].get('css', [])) nonce = str(uuid4()) html = render_template('previewer_jupyter:ipynb_preview.html', attachment=self.attachment, html_code=body, css_code=css_code, nonce=nonce) response = current_app.response_class(html) # Use CSP to restrict access to possibly malicious scripts or inline JS csp_header = "script-src cdn.mathjax.org 'nonce-{}';".format(nonce) response.headers['Content-Security-Policy'] = csp_header response.headers['X-Webkit-CSP'] = csp_header # IE10 doesn't have proper CSP support, so we need to be more strict response.headers['X-Content-Security-Policy'] = "sandbox allow-same-origin;" return response
def _process(self): config = Config() config.HTMLExporter.preprocessors = [CppHighlighter] config.HTMLExporter.template_file = 'basic' with self.attachment.file.open() as f: notebook = nbformat.read(f, as_version=4) html_exporter = HTMLExporter(config=config) body, resources = html_exporter.from_notebook_node(notebook) css_code = '\n'.join(resources['inlining'].get('css', [])) nonce = str(uuid4()) html = render_template('previewer_jupyter:ipynb_preview.html', attachment=self.attachment, html_code=body, css_code=css_code, nonce=nonce) response = current_app.response_class(html) # Use CSP to restrict access to possibly malicious scripts or inline JS csp_header = "script-src cdn.mathjax.org 'nonce-{}';".format(nonce) response.headers['Content-Security-Policy'] = csp_header response.headers['X-Webkit-CSP'] = csp_header # IE10 doesn't have proper CSP support, so we need to be more strict response.headers[ 'X-Content-Security-Policy'] = "sandbox allow-same-origin;" return response
async def render(notebook_id: str = ID_VALIDATOR): traitlets_config = { "Highlight2HTML": { "extra_formatter_options": { "linenos": "table" } } } exporter = HTMLExporter( # Input / output prompts are empty left gutter space # Let's remove them. If we want gutters, we can CSS them. exclude_input_prompt=True, exclude_output_prompt=True, extra_template_basedirs=[BASE_PATH], template_name="nbconvert-template", config=traitlets_config, ) data, metadata = await backend.get(notebook_id) if data is None: # No data found raise HTTPException(status_code=404) if metadata.format == "html": # R notebooks # I HATE THIS BUT WHAT TO DO? # We need notebook.js inside the iframe to respond to messages, # and resize iframe appropriately. We don't have control over the HTML # and I don't want to parse it. Instead, we just shove this in there. # VALID HTML!? WHO KNOWS?! output = "<script src='/static/notebook.js'></script>\n" + data.decode( ) else: if metadata.format == "ipynb": notebook = nbformat.reads(data.decode(), as_version=4) else: config = JupytextConfiguration() # Don't put Rmd and other 'front matter' as a raw cell in the notebook output # Ideally we'd be able to parse this and display it nicely, but lacking that # let's not output some raw YAML in the display. config.root_level_metadata_as_raw_cell = False notebook = jupytext.reads(data.decode(), metadata.format, config=config) output, resources = exporter.from_notebook_node( notebook, {"object_metadata": metadata}) return HTMLResponse( output, headers={ # Disable embedding our rendered notebook in other websites # Don't want folks hotlinking our renders. "Content-Security-Policy": "frame-ancestors 'self';", "X-Frame-Options": "SAMEORIGIN", # Intensely cache everything here. # We can cache bust by purging everything with the cloudflare API, # or with query params. This is much simpler than caching on # the server side "Cache-Control": "public, max-age=604800, immutable", }, )
def _compile_string(self, nb_json): """Export notebooks as HTML strings.""" if flag is None: req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)') c = Config(self.site.config['IPYNB_CONFIG']) exportHtml = HTMLExporter(config=c) body, _ = exportHtml.from_notebook_node(nb_json) return body
def _compile_string(self, nb_json): """Export notebooks as HTML strings.""" self._req_missing_ipynb() c = Config(self.site.config['IPYNB_CONFIG']) c.update(get_default_jupyter_config()) exportHtml = HTMLExporter(config=c) body, _ = exportHtml.from_notebook_node(nb_json) return body
def render_ipynb(full_path): """ Render a given ipynb file """ exporter = HTMLExporter() with open(full_path, encoding='utf-8') as file_handle: html, res = exporter.from_file(file_handle) return Response(html, mimetype='text/html')
def to_html(self): cb_name = self.nb_buffer.name.split('/')[-1] notebook_name = cb_name.split('.')[0] self.write_buffer() html_exporter = HTMLExporter(config=self.c) html_exporter.template_file = 'full' body, resources = html_exporter.from_filename(cb_name) self.writer.write(body, resources, notebook_name = notebook_name)
def render_ipynb(full_path, format): """ Render a given ipynb file """ exporter = HTMLExporter() with open(full_path, encoding="utf-8") as file_handle: html, _ = exporter.from_file(file_handle) return Response(html, mimetype="text/html")
def get_html_from_filepath(filepath, start=0, end=None, template=None): """Return the HTML from a Jupyter Notebook """ preprocessors_ = [SubCell] template_file = "basic" extra_loaders = [] if template: extra_loaders.append( jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) # Load the user's nbconvert configuration app = NbConvertApp() app.load_config_file() app.config.update({ # This Preprocessor changes the pygments css prefixes # from .highlight to .highlight-ipynb "CSSHTMLHeaderPreprocessor": { "enabled": True, "highlight_class": ".highlight-ipynb", }, "SubCell": { "enabled": True, "start": start, "end": end }, }) # Overwrite Custom jinja filters # This is broken right now so needs fix from below # https://github.com/jupyter/nbconvert/pull/877 filters = { "highlight_code": custom_highlight_code } exporter = HTMLExporter( config=app.config, template_file=template_file, extra_loaders=extra_loaders, filters=filters, preprocessors=preprocessors_, ) content, info = exporter.from_filename(filepath) # Fix for nbconvert bug # content = content.replace("<pre>", '<pre class="highlight highlight-ipynb">') # end-fix # Since we make a Markdown file we need to remove empty lines and strip content = "\n".join([line.rstrip() for line in content.split("\n") if line.rstrip()]) return content, info
def _compile_string(self, nb_json): """Export notebooks as HTML strings.""" if flag is None: req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)') c = Config(self.site.config['IPYNB_CONFIG']) c.update(get_default_jupyter_config()) exportHtml = HTMLExporter(config=c) body, _ = exportHtml.from_notebook_node(nb_json) return body
def get_html_from_filepath(filepath, start=0, end=None, template=None, execute=False): """Return the HTML from a Jupyter Notebook """ preprocessors_ = [SubCell] template_file = "basic" extra_loaders = [] if template: extra_loaders.append( jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) # Load the user's nbconvert configuration app = NbConvertApp() app.load_config_file() app.config.update({ # This Preprocessor changes the pygments css prefixes # from .highlight to .highlight-ipynb "CSSHTMLHeaderPreprocessor": { "enabled": True, "highlight_class": ".highlight-ipynb", }, "SubCell": { "enabled": True, "start": start, "end": end }, # "ExecutePreprocessor": { # "enabled": execute, # "store_widget_state": True # } }) # Overwrite Custom jinja filters # This is broken right now so needs fix from below # https://github.com/jupyter/nbconvert/pull/877 # TODO: is this fixed and released? filters = { "highlight_code": custom_highlight_code, } exporter = HTMLExporter( config=app.config, template_file=template_file, preprocessors=preprocessors_, extra_loaders=extra_loaders, filters=filters, ) content, info = exporter.from_filename(filepath) return content, info
def render_notebook(self, filename, site=None, data=None, lang=None, post=None): c = Config(self.site.config['IPYNB_CONFIG']) export_html = HTMLExporter(config=c) (notebook_raw, _) = export_html.from_filename(filename) # The raw HTML contains garbage (scripts and styles). Extract only div id=notebook-container and children notebook_html = lxml.html.fromstring(notebook_raw) notebook_code = lxml.html.tostring(notebook_html.xpath('//*[@id="notebook-container"]')[0], encoding='unicode') return notebook_code, [filename]
def _compile_string(self, nb_json): """Export notebooks as HTML strings.""" self._req_missing_ipynb() c = Config(get_default_jupyter_config()) c.merge(Config(self.site.config['IPYNB_CONFIG'])) if 'template_file' not in self.site.config['IPYNB_CONFIG'].get('Exporter', {}): c['Exporter']['template_file'] = 'basic.tpl' # not a typo exportHtml = HTMLExporter(config=c) body, _ = exportHtml.from_notebook_node(nb_json) return body
def compile_html_string(self, source, is_two_file=True): """Export notebooks as HTML strings.""" if flag is None: req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)') c = Config(self.site.config['IPYNB_CONFIG']) exportHtml = HTMLExporter(config=c) with io.open(source, "r", encoding="utf8") as in_file: nb_json = nbformat.read(in_file, current_nbformat) (body, resources) = exportHtml.from_notebook_node(nb_json) return body
def generate_exercises(): p = Path(*EXERCISES_DIR) exporter = HTMLExporter() exporter.register_preprocessor(ClearOutputPreprocessor(), enabled=True) for exercise in p.iterdir(): if exercise.suffix == '.ipynb': html, _ = exporter.from_file(exercise.open()) with open(exercise.with_suffix('.html').name, 'w') as f: f.write(html)
def _compile_string(self, nb_json): """Export notebooks as HTML strings.""" self._req_missing_ipynb() c = Config(self.site.config['IPYNB_CONFIG']) c.update(get_default_jupyter_config()) if 'template_file' not in self.site.config['IPYNB_CONFIG'].get('Exporter', {}): c['Exporter']['template_file'] = 'basic.tpl' # not a typo exportHtml = HTMLExporter(config=c) body, _ = exportHtml.from_notebook_node(nb_json) return body
def nb2html(nb_path, start=0, end=None, execute=False, kernel_name=""): """Convert a notebook and return html""" logger.info(f"Convert notebook {nb_path}") # Load the user's nbconvert configuration app = NbConvertApp() app.load_config_file() app.config.update( { # This Preprocessor changes the pygments css prefixes # from .highlight to .highlight-ipynb "CSSHTMLHeaderPreprocessor": { "enabled": True, "highlight_class": ".highlight-ipynb", }, "SubCell": {"enabled": True, "start": start, "end": end}, "ExecutePreprocessor": { "enabled": execute, "store_widget_state": True, "kernel_name": kernel_name, }, } ) preprocessors_ = [SubCell] filters = { "highlight_code": custom_highlight_code, } template_file = "mkdocs_html/notebook.html.j2" # template_file = "lab/index.html.j2" exporter = HTMLExporter( config=app.config, template_file=template_file, # uncomment this line when new nbconvert is released # https://github.com/jupyter/nbconvert/pull/1429 extra_template_paths=[os.path.join(THIS_DIR, "templates")], preprocessors=preprocessors_, filters=filters, ) # Delete this block when nbconvert is released # https://github.com/jupyter/nbconvert/pull/1429 # exporter.template_paths.append(os.path.join(THIS_DIR, "templates")) # print(exporter.template_paths) # End block html, info = exporter.from_filename(nb_path) # HTML and CSS fixes # html = html_fixes(html, info, fix_css=True, ignore_css=False) return GENERATED_MD.format(html=html)
def compile_string(self, source, is_two_file=True): """Export notebooks as HTML strings.""" if flag is None: req_missing(['ipython[notebook]>=2.0.0'], 'build this site (compile ipynb)') c = Config(self.site.config['IPYNB_CONFIG']) exportHtml = HTMLExporter(config=c) with io.open(source, "r", encoding="utf8") as in_file: nb_json = nbformat.read(in_file, current_nbformat) (body, resources) = exportHtml.from_notebook_node(nb_json) return body
def get_html_from_filepath(filepath, start=0, end=None, template=None): """Return the HTML from a Jupyter Notebook """ preprocessors_ = [SubCell] template_file = "basic" extra_loaders = [] if template: extra_loaders.append( jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) # Load the user's nbconvert configuration app = NbConvertApp() app.load_config_file() app.config.update({ # This Preprocessor changes the pygments css prefixes # from .highlight to .highlight-ipynb "CSSHTMLHeaderPreprocessor": { "enabled": True, "highlight_class": ".highlight-ipynb", }, "SubCell": { "enabled": True, "start": start, "end": end }, }) # Overwrite Custom jinja filters # This is broken right now so needs fix from below # https://github.com/jupyter/nbconvert/pull/877 filters = {"highlight_code": custom_highlight_code} exporter = HTMLExporter( config=app.config, template_file=template_file, extra_loaders=extra_loaders, filters=filters, preprocessors=preprocessors_, ) content, info = exporter.from_filename(filepath) # Fix for nbconvert bug content = content.replace("<pre>", '<pre class="highlight highlight-ipynb">') # end-fix # Since we make a Markdown file we need to remove empty lines and strip content = "\n".join( [line.strip() for line in content.split("\n") if line.strip()]) return content, info
def trace_get_func(job, func): if func == "custom.css": return "" from nbconvert.exporters import HTMLExporter exporter = HTMLExporter() fn = os.path.join(tempfile.gettempdir(), job, func+"_output.ipynb") output, resources = exporter.from_filename(fn) return output
def convert_ipynb_to_html(notebook_file, html_file): """ Convert the given `notebook_file` to HTML and write it to `html_file`. """ # set a high timeout for datasets with a large number of features report_config = Config({'ExecutePreprocessor': {'enabled': True, 'timeout': 600}, 'HTMLExporter': {'template_path': [template_path], 'template_file': 'report.tpl'}}) exportHtml = HTMLExporter(config=report_config) output, resources = exportHtml.from_filename(notebook_file) open(html_file, mode='w', encoding='utf-8').write(output)
def main(app): static_dir = os.path.join(app.builder.srcdir, '_static') target_dir = os.path.join(app.builder.srcdir, 'notebooks') source_dir = os.path.abspath( os.path.join(app.builder.srcdir, '..', 'notebooks')) rendered_dir = os.path.join(target_dir, 'rendered') if not os.path.exists(static_dir): os.makedirs(static_dir) if not os.path.exists(target_dir): os.makedirs(target_dir) if not os.path.exists(rendered_dir): os.makedirs(rendered_dir) nbroots = [] nbtitles = [] exporter = HTMLExporter(template_file='full') for nb_src in glob.glob(os.path.join(source_dir, '*.ipynb')): print("converting notebook {0}".format(nb_src)) basedir, nbname = os.path.split(nb_src) nb_dest = os.path.join(target_dir, nbname) shutil.copyfile(nb_src, nb_dest) with open(nb_dest, 'r') as f: nb_json = nbformat.reads(f.read(), as_version=4) (body, resources) = exporter.from_notebook_node(nb_json) root, ext = os.path.splitext(nbname) nb_html_dest = os.path.join(rendered_dir, root + '.html') with open(nb_html_dest, 'w') as f: f.write(body) nbroots.append(root) nbtitles.append(get_notebook_title(nb_json, root)) for nbroot, nbtitle in zip(nbroots, nbtitles): with open(os.path.join(target_dir, nbroot + '.rst'), 'w') as f: f.write(RST_TEMPLATE.render(title=nbtitle, nbroot=nbroot)) with open(os.path.join(target_dir, 'index.rst'), 'w') as f: f.write( INDEX_TEMPLATE.render(notebooks=nbroots, sphinx_tag='notebook-examples'))
def get_html_from_filepath(filepath): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({"CSSHTMLHeaderTransformer": {"enabled": True, "highlight_class": ".highlight-ipynb"}}) exporter = HTMLExporter(config=config, template_file="basic", filters={"highlight2html": custom_highlighter}) content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content, "html.parser") for i in soup.findAll("div", {"class": "input"}): if i.findChildren()[1].find(text="#ignore") is not None: i.extract() content = soup.decode(formatter=None) return content, info
def start(self): super(FormgradeApp, self).start() # Init authenticator. self.authenticator_instance = self.authenticator_class( app, self.ip, self.port, self.base_directory, parent=self) app.auth = self.authenticator_instance # now launch the formgrader app.notebook_dir = self.base_directory app.notebook_dir_format = self.directory_structure app.nbgrader_step = self.autograded_directory app.exporter = HTMLExporter(config=self.config) app.mathjax_url = self.mathjax_url url = "http://{:s}:{:d}/".format(self.ip, self.port) self.log.info("Form grader running at {}".format(url)) self.log.info("Use Control-C to stop this server") app.gradebook = Gradebook(self.db_url) app.run(host=self.ip, port=self.port, debug=True, use_reloader=False)
def init_tornado_settings(self, webapp): # Init jinja environment jinja_env = Environment( loader=FileSystemLoader([handlers.template_path])) course_dir = self.coursedir.root notebook_dir = self.parent.notebook_dir relpath = os.path.relpath(course_dir, notebook_dir) if relpath.startswith("../"): nbgrader_bad_setup = True self.log.error( "The course directory root is not a subdirectory of the notebook " "server root. This means that nbgrader will not work correctly. " "If you want to use nbgrader, please ensure the course directory " "root is in a subdirectory of the notebook root: %s", notebook_dir) else: nbgrader_bad_setup = False # Configure the formgrader settings tornado_settings = dict( nbgrader_url_prefix=os.path.relpath(self.coursedir.root, self.parent.notebook_dir), nbgrader_coursedir=self.coursedir, nbgrader_exporter=HTMLExporter(config=self.config), nbgrader_gradebook=None, nbgrader_db_url=self.coursedir.db_url, nbgrader_jinja2_env=jinja_env, nbgrader_bad_setup=nbgrader_bad_setup) webapp.settings.update(tornado_settings)
def _build_head() -> str: import nbformat from nbconvert.exporters import HTMLExporter path = importlib_resources.files( "miyadaiku.themes.ipynb") / EMPTY_IPYNB # type: ignore src = path.read_bytes() json = nbformat.reads(src, nbformat.current_nbformat) html, _ = HTMLExporter({}).from_notebook_node(json) soup = BeautifulSoup(html, "html.parser") soup.head.title.extract() soup.body.extract() soup.head.unwrap() soup.html.unwrap() for x in soup.children: if isinstance(x, Doctype): x.extract() if x.name == "meta": x.extract() return str(soup)
def main(app): static_dir = os.path.join(app.builder.srcdir, '_static') target_dir = os.path.join(app.builder.srcdir, 'notebooks') source_dir = os.path.abspath(os.path.join(app.builder.srcdir, '..', 'notebooks')) rendered_dir = os.path.join(target_dir, 'rendered') if not os.path.exists(static_dir): os.makedirs(static_dir) if not os.path.exists(target_dir): os.makedirs(target_dir) if not os.path.exists(rendered_dir): os.makedirs(rendered_dir) nbroots = [] nbtitles = [] exporter = HTMLExporter(template_file='full') for nb_src in glob.glob(os.path.join(source_dir, '*.ipynb')): print("converting notebook {0}".format(nb_src)) basedir, nbname = os.path.split(nb_src) nb_dest = os.path.join(target_dir, nbname) shutil.copyfile(nb_src, nb_dest) with open(nb_dest, 'r') as f: nb_json = nbformat.reads(f.read(), as_version = 4) (body, resources) = exporter.from_notebook_node(nb_json) root, ext = os.path.splitext(nbname) nb_html_dest = os.path.join(rendered_dir, root + '.html') with open(nb_html_dest, 'w') as f: f.write(body) nbroots.append(root) nbtitles.append(get_notebook_title(nb_json, root)) for nbroot, nbtitle in zip(nbroots, nbtitles): with open(os.path.join(target_dir, nbroot + '.rst'), 'w') as f: f.write(RST_TEMPLATE.render(title=nbtitle, nbroot=nbroot)) with open(os.path.join(target_dir, 'index.rst'), 'w') as f: f.write(INDEX_TEMPLATE.render(notebooks=nbroots, sphinx_tag='notebook-examples'))
def render(self): try: with open(self.file_path, 'r') as file_pointer: notebook = nbformat.reads(file_pointer.read(), as_version=4) except ValueError: raise exceptions.InvalidFormat('Could not read ipython notebook file.') exporter = HTMLExporter(config=Config({ 'HTMLExporter': { 'template_file': 'basic', }, 'CSSHtmlHeaderTransformer': { 'enabled': False, }, })) (body, _) = exporter.from_notebook_node(notebook) return self.TEMPLATE.render(base=self.assets_url, body=body)
def render_notebook(self, filename, site=None, data=None, lang=None, post=None): c = Config(self.site.config['IPYNB_CONFIG']) export_html = HTMLExporter(config=c) (notebook_raw, _) = export_html.from_filename(filename) # The raw HTML contains garbage (scripts and styles). Extract only div id=notebook-container and children notebook_html = lxml.html.fromstring(notebook_raw) notebook_code = lxml.html.tostring( notebook_html.xpath('//*[@id="notebook-container"]')[0], encoding='unicode') return notebook_code, [filename]
def get_html_from_filepath(filepath): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({'CSSHTMLHeaderTransformer': {'enabled': True, 'highlight_class': '.highlight-ipynb'}}) config.HTMLExporter.preprocessors = [HtmlLinksPreprocessor] config.HtmlLinksPreprocessor['enabled'] = True path = os.path.dirname(os.path.realpath(__file__)) exporter = HTMLExporter(config=config, template_file='no_code', template_path=['.', path + '/../../../scripts/'], filters={'highlight2html': custom_highlighter}) content, info = exporter.from_filename(filepath) return content, info
def test_widgets_from_htmlexporter(self): """Check jupyter widgets URL""" with self.create_temp_cwd(["Widget_List.ipynb"]) as tmpdir: with open(os.path.join(tmpdir, 'Widget_List.ipynb')) as f: nb = nbformat.read(f, 4) output, _ = HTMLExporter().from_notebook_node(nb) assert "var widgetRendererSrc = 'https://unpkg.com/@jupyter-widgets/html-manager@*/dist/embed-amd.js';" in output
def _convert(self, tmpdir: Path, entry: Path, outdir: Path, depth: int): """Convert a notebook. Args: tmpdir: Temporary working directory entry: notebook to convert outdir: output directory for .html and .rst files depth: depth below root, for fixing image paths """ test_mode = self.s.get("test_mode") # strip special cells. if self._has_tagged_cells(entry, set(self._cell_tags.values())): _log.debug(f"notebook '{entry.name}' has test cell(s)") orig_entry, entry = entry, self._strip_tagged_cells( tmpdir, entry, ("remove", "exercise"), "testing") notify(f"Stripped tags from: {orig_entry.name}", 3) else: # copy to temporary directory just to protect from output cruft tmp_entry = tmpdir / entry.name shutil.copy(entry, tmp_entry) orig_entry, entry = entry, tmp_entry # convert all tag-stripped versions of the notebook. # before running, check if converted result is newer than source file if self._already_converted(orig_entry, entry, outdir): notify( f"Skip notebook conversion, output is newer, for: {entry.name}", 3) self._results.cached.append(entry) return notify(f"Running notebook: {entry.name}", 3) nb = self._parse_and_execute(entry) if test_mode: # don't do conversion in test mode return notify(f"Exporting notebook '{entry.name}' to directory {outdir}", 3) wrt = FilesWriter() # export each notebook into multiple target formats created_wrapper = False for (exp, postprocess_func, pp_args) in ( (RSTExporter(), self._postprocess_rst, ()), (HTMLExporter(), self._postprocess_html, (depth, )), ): _log.debug( f"export '{orig_entry}' with {exp} to notebook '{entry}'") (body, resources) = exp.from_notebook_node(nb) body = postprocess_func(body, *pp_args) wrt.build_directory = str(outdir) wrt.write(body, resources, notebook_name=entry.stem) # create a 'wrapper' page if not created_wrapper: _log.debug( f"create wrapper page for '{entry.name}' in '{outdir}'") self._create_notebook_wrapper_page(entry.stem, outdir) created_wrapper = True # move notebooks into docs directory _log.debug(f"move notebook '{entry} to output directory: {outdir}") shutil.copy(entry, outdir / entry.name)
def get_html_from_filepath(filepath): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({'CSSHTMLHeaderTransformer': {'enabled': True, 'highlight_class': '.highlight-ipynb'}}) exporter = HTMLExporter(config=config, template_file='basic') exporter.register_filter('markdown2html', filters.markdown2html_pandoc) content, info = exporter.from_filename(filepath) soup = BeautifulSoup(content, "html.parser") for i in soup.findAll("div", {"class": "input"}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup.decode(formatter=None) return content, info
def nb_to_html(nb_path): """convert notebook to html""" exporter = HTMLExporter(template_file='full') output, resources = exporter.from_filename(nb_path) header = output.split('<head>', 1)[1].split('</head>',1)[0] body = output.split('<body>', 1)[1].split('</body>',1)[0] # http://imgur.com/eR9bMRH header = header.replace('<style', '<style scoped="scoped"') header = header.replace('body {\n overflow: visible;\n padding: 8px;\n}\n', '') header = header.replace("code,pre{", "code{") header = header.replace('\n', '') comp = re.compile('<style.*?</style>', re.MULTILINE) header = comp.sub('', header) # Filter out styles that conflict with the sphinx theme. filter_strings = [ 'navbar', 'body{', 'alert{', 'uneditable-input{', 'collapse{', ] filter_strings.extend(['h%s{' % (i+1) for i in range(6)]) line_begin_strings = [ 'pre{', 'p{margin' ] header_lines = filter( lambda x: not any([s in x for s in filter_strings]), header.split('\n')) header_lines = filter( lambda x: not any([x.startswith(s) for s in line_begin_strings]), header_lines) header = '\n'.join(header_lines) # fix wrong static links to headers body = body.replace('class="anchor-link"', 'class="headerlink"') # concatenate raw html lines lines = ['<div class="ipynotebook">', header, body, '</div>'] return '\n'.join(lines)
def get_html_from_filepath(filepath, start=0, end=None, preprocessors=[], template=None, colorscheme=None): """Return the HTML from a Jupyter Notebook """ template_file = "basic" extra_loaders = [] if template: extra_loaders.append( jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) config = get_config() config.update({ "CSSHTMLHeaderTransformer": { "enabled": True, "highlight_class": ".highlight-ipynb", }, "SubCell": { "enabled": True, "start": start, "end": end }, }) if not colorscheme: colorscheme = "default" config.CSSHTMLHeaderPreprocessor.highlight_class = " .highlight pre " config.CSSHTMLHeaderPreprocessor.style = colorscheme config.LatexPreprocessor.style = colorscheme exporter = HTMLExporter( config=config, template_file=template_file, extra_loaders=extra_loaders, filters={"highlight2html": custom_highlighter}, preprocessors=[SubCell] + preprocessors, ) content, info = exporter.from_filename(filepath) return content, info
def get_html_from_filepath(filepath): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({'CSSHTMLHeaderTransformer': {'enabled': True, 'highlight_class': '.highlight-ipynb'}}) exporter = HTMLExporter(config=config, template_file='basic', filters={'highlight2html': custom_highlighter}) content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content) for i in soup.findAll("div", {"class" : "input"}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup return content, info
def get_html_from_filepath(filepath, start=0, end=None, preprocessors=[], template=None): """Convert ipython notebook to html Return: html content of the converted notebook """ template_file = 'basic' extra_loaders = [] if template: extra_loaders.append( jinja2.FileSystemLoader([os.path.dirname(template)])) template_file = os.path.basename(template) config = Config({ 'CSSHTMLHeaderTransformer': { 'enabled': True, 'highlight_class': '.highlight-ipynb' }, 'SubCell': { 'enabled': True, 'start': start, 'end': end } }) exporter = HTMLExporter(config=config, template_file=template_file, extra_loaders=extra_loaders, filters={'highlight2html': custom_highlighter}, preprocessors=[SubCell] + preprocessors) config.CSSHTMLHeaderPreprocessor.highlight_class = " .highlight pre " content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content, 'html.parser') for i in soup.findAll('div', {'class': 'input'}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup.decode(formatter="minimal") return content, info
def get_html_from_filepath(filepath, template=None, start=0, end=None, no_prompts=False): """Convert ipython notebook to html Return: html content of the converted notebook """ if template is None: template = 'basic' config = Config({ 'CSSHTMLHeaderTransformer': { 'enabled': True, 'highlight_class': '.highlight-ipynb' }, 'SubCell': { 'enabled': True, 'start': start, 'end': end } }) exporter = HTMLExporter(config=config, template_file=template, filters={'highlight2html': custom_highlighter}, preprocessors=[SubCell]) # Remove all the input and output prompts from the exported HTML, this extends the width of # all cells,, not just the input and output cells. if no_prompts: exporter.exclude_input_prompt = True exporter.exclude_output_prompt = True content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content, 'html.parser') for i in soup.findAll('div', {'class': 'input'}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup.decode(formatter=None) return content, info
def get_html_from_filepath(filepath, start=0, end=None): """Convert ipython notebook to html Return: html content of the converted notebook """ config = Config({'CSSHTMLHeaderTransformer': {'enabled': True, 'highlight_class': '.highlight-ipynb'}, 'SubCell': {'enabled':True, 'start':start, 'end':end}}) exporter = HTMLExporter(config=config, template_file='basic', filters={'highlight2html': custom_highlighter}, preprocessors=[SubCell]) content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content, 'html.parser') for i in soup.findAll('div', {'class': 'input'}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() content = soup.decode(formatter=None) return content, info
def render(self): try: with open(self.file_path, 'r') as file_pointer: notebook = nbformat.reads(file_pointer.read(), as_version=4) except ValueError as err: raise exceptions.InvalidFormatError( 'Could not read ipython notebook file. {}'.format(str(err)), extension=self.metadata.ext, download_url=str(self.metadata.download_url), original_exception=err, ) exporter = HTMLExporter(config=Config({ 'HTMLExporter': { 'template_file': 'basic', }, 'CSSHtmlHeaderTransformer': { 'enabled': False, }, })) (body, _) = exporter.from_notebook_node(notebook) return self.TEMPLATE.render(base=self.assets_url, body=body)
def notebook(preprocessor, tag, markup): match = FORMAT.search(markup) if match: argdict = match.groupdict() src = argdict["src"] start = argdict["start"] end = argdict["end"] language = argdict["language"] else: raise ValueError("Error processing input, " "expected syntax: {0}".format(SYNTAX)) if start: start = int(start) else: start = 0 if end: end = int(end) else: end = None language_applied_highlighter = partial(custom_highlighter, language=language) nb_dir = preprocessor.configs.getConfig("NOTEBOOK_DIR") nb_path = os.path.join("content", nb_dir, src) if not os.path.exists(nb_path): raise ValueError("File {0} could not be found".format(nb_path)) # Create the custom notebook converter c = Config( { "CSSHTMLHeaderTransformer": {"enabled": True, "highlight_class": ".highlight-ipynb"}, "SubCell": {"enabled": True, "start": start, "end": end}, } ) template_file = "basic" if IPYTHON_VERSION >= 3: if os.path.exists("pelicanhtml_3.tpl"): template_file = "pelicanhtml_3" elif IPYTHON_VERSION == 2: if os.path.exists("pelicanhtml_2.tpl"): template_file = "pelicanhtml_2" else: if os.path.exists("pelicanhtml_1.tpl"): template_file = "pelicanhtml_1" if IPYTHON_VERSION >= 2: subcell_kwarg = dict(preprocessors=[SubCell]) else: subcell_kwarg = dict(transformers=[SubCell]) exporter = HTMLExporter( config=c, template_file=template_file, filters={"highlight2html": language_applied_highlighter}, **subcell_kwarg ) # read and parse the notebook with open(nb_path) as f: nb_text = f.read() if IPYTHON_VERSION < 3: nb_json = IPython.nbformat.current.reads_json(nb_text) else: try: nb_json = nbformat.reads(nb_text, as_version=4) except: nb_json = IPython.nbformat.reads(nb_text, as_version=4) (body, resources) = exporter.from_notebook_node(nb_json) # if we haven't already saved the header, save it here. if not notebook.header_saved: print("\n ** Writing styles to _nb_header.html: " "this should be included in the theme. **\n") header = "\n".join(CSS_WRAPPER.format(css_line) for css_line in resources["inlining"]["css"]) header += JS_INCLUDE with open("_nb_header.html", "w") as f: f.write(header) notebook.header_saved = True # this will stash special characters so that they won't be transformed # by subsequent processes. body = preprocessor.configs.htmlStash.store(body, safe=True) return body
def read(self, filepath): metadata = {} # Files filedir = os.path.dirname(filepath) filename = os.path.basename(filepath) metadata_filename = filename.split('.')[0] + '.ipynb-meta' metadata_filepath = os.path.join(filedir, metadata_filename) # Load metadata if os.path.exists(metadata_filepath): # Metadata is on a external file, process using Pelican MD Reader md_reader = MarkdownReader(self.settings) _content, metadata = md_reader.read(metadata_filepath) else: # Load metadata from ipython notebook file ipynb_file = open(filepath) metadata = json.load(ipynb_file)['metadata'] # Fix metadata to pelican standards for key, value in metadata.items(): del metadata[key] key = key.lower() metadata[key] = self.process_metadata(key, value) metadata['ipython'] = True # Convert ipython notebook to html config = Config({'CSSHTMLHeaderTransformer': {'enabled': True, 'highlight_class': '.highlight-ipynb'}}) exporter = HTMLExporter(config=config, template_file='basic', filters={'highlight2html': custom_highlighter}) content, info = exporter.from_filename(filepath) if BeautifulSoup: soup = BeautifulSoup(content) for i in soup.findAll("div", {"class" : "input"}): if i.findChildren()[1].find(text='#ignore') is not None: i.extract() else: soup = content # Process using Pelican HTMLReader content = '<body>{0}</body>'.format(soup) # So Pelican HTMLReader works parser = MyHTMLParser(self.settings, filename) parser.feed(content) parser.close() body = parser.body if ('IPYNB_USE_META_SUMMARY' in self.settings.keys() and \ self.settings['IPYNB_USE_META_SUMMARY'] == False) or \ 'IPYNB_USE_META_SUMMARY' not in self.settings.keys(): metadata['summary'] = parser.summary def filter_css(style_text): ''' HACK: IPython returns a lot of CSS including its own bootstrap. Get only the IPython Notebook CSS styles. ''' index = style_text.find('/*!\n*\n* IPython notebook\n*\n*/') if index > 0: style_text = style_text[index:] index = style_text.find('/*!\n*\n* IPython notebook webapp\n*\n*/') if index > 0: style_text = style_text[:index] style_text = re.sub(r'color\:\#0+(;)?', '', style_text) style_text = re.sub(r'\.rendered_html[a-z0-9,._ ]*\{[a-z0-9:;%.#\-\s\n]+\}', '', style_text) return '<style type=\"text/css\">{0}</style>'.format(style_text) ipython_css = '\n'.join(filter_css(css_style) for css_style in info['inlining']['css']) body = ipython_css + body + LATEX_CUSTOM_SCRIPT return body, metadata
#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import sys reload(sys) sys.setdefaultencoding("utf-8") from nbconvert.exporters import HTMLExporter from traitlets.config import Config config = Config({ "HTMLExporter": {"template_file": "basic"}, 'NbConvertBase': { 'display_data_priority': [ 'text/html', 'text/markdown', 'application/pdf', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain', ] } }) ex = HTMLExporter(config=config) html, extra = ex.from_file(sys.stdin) sys.stdout.write(html)
def get(self, prepath, user, filename): ## filename can have a path on it next = "/%s/hub/%s/public/%s" % (prepath, user, filename) filesystem_path = "/home/%s/public_html/%s" % (user, filename) if os.path.isfile(filesystem_path): # download, raw, or view notebook command = "view" if len(self.get_arguments("view")) > 0: command = "view" elif len(self.get_arguments("download")) > 0: command = "download" elif len(self.get_arguments("copy")) > 0: command = "copy" elif len(self.get_arguments("pdf")) > 0: command = "pdf" elif len(self.get_arguments("raw")) > 0: command = "raw" # else: view if filename.endswith(".ipynb"): if command in ["view", "pdf"]: # first, make a notebook html: #with open("/home/%s/public_html/%s" % (user, filename)) as fp: # notebook_content = fp.read() if command == "view": exporter = HTMLExporter(template_file='full-tabs') else: exporter = PDFExporter(latex_count=1) nb_json = nbformat.read("/home/%s/public_html/%s" % (user, filename), as_version=4) #if command == "pdf": # # If pdf, remove heading numbering: # for cell in nb_json["worksheets"][0]["cells"]: # if cell["cell_type"] == "heading": # cell["source"] = re.sub("^([0-9]+\.?)+\s", "", cell["source"]) # where to get css, images? if command == "pdf": self.set_header('Content-Type', "application/pdf") base_filename = os.path.basename(filename) self.set_header('Content-Disposition', 'attachment; filename="%s"' % base_filename) else: # render as HTML # add header/footer: path = "/%s/hub/%s/public" % (prepath, user) parts = [(path, path)] for part in filename.split("/")[:-1]: path += "/" + part parts.append((path, part)) breadcrumbs = " / ".join(map(lambda pair: '<a href="%s" target="_blank">%s</a>' % pair, parts)) env = { "breadcrumbs": breadcrumbs, "url": "https://athena.brynmawr.edu/" + next + "?download" } cell = new_markdown_cell(source="""<table width="100%" style="border: none;"> <tr style="border: none;"> <td style="border: none;" width="100px"> <img src="https://blog.jupyter.org/content/images/2015/02/jupyter-sq-text.png" width="100"/> </td> <td style="border: none;" width="50%"> <h2><a href="https://athena.brynmawr.edu/">Jupyter at Bryn Mawr College</a></h2> </td> <td style="border: none;"> <a href="https://athena.brynmawr.edu/jupyter/hub/dblank/public/Jupyter%20Help.ipynb" title="Help"> <span class="fa fa-info-circle fa-2x menu-icon"></span> <span class="menu-text">Help</span> </a> </td> <td style="border: none;"> <a href="{url}" title="Download Notebook" download> <span class="fa fa-download fa-2x menu-icon"></span> <span class="menu-text">Download Notebook</span> </a> </td> </tr> <tr style="border: none;"> <td colspan="4" style="border: none;"> <b>Public notebooks:</b> {breadcrumbs} </td> </tr> </table>""".format(**env)) nb_json["cells"].insert(0, cell) (body, resources) = exporter.from_notebook_node(nb_json) self.write(body) elif command == "download": # download notebook json self.download(user, filename, "text/plain") elif command == "copy": # copy notebook json, if logged in if self.get_current_user_name(): self.copy_file(user, filename, self.get_current_user_name()) else: self.write("Please <a href=\"/%s/hub/login?next=%s\">login</a> to allow copy." % (prepath, next)) else: # raw, just get file contents with open("/home/%s/public_html/%s" % (user, filename), "rb") as fp: self.write(fp.read()) else: # some other kind of file # FIXME: how to get all of custom stuff? if command == "copy": if self.get_current_user_name(): self.copy_file(user, filename, self.get_current_user_name()) else: self.write("Please <a href=\"/%s/hub/login?next=%s\">login</a> to allow copy." % (prepath, next)) else: # whatever, just get or download it base_filename = os.path.basename(filename) base, ext = os.path.splitext(base_filename) app_log.info("extension is: %s" % ext) if base_filename == "custom.css": file_path = "/home/%s/.ipython/profile_default/static/custom/custom.css" % user self.set_header('Content-Type', "text/css") with open(file_path, "rb") as fp: self.write(fp.read()) elif ext in [".txt", ".html", ".js", ".css", ".pdf", ".gif", ".jpeg", ".jpg", ".png"]: # show in browser app_log.info("mime: %s" % str(mimetypes.guess_type(filename)[0])) self.set_header('Content-Type', mimetypes.guess_type(filename)[0]) with open("/home/%s/public_html/%s" % (user, filename), "rb") as fp: self.write(fp.read()) else: self.download(user, filename) else: # not a file; directory listing # filename can have a full path, and might be empty url_path = "/%s/hub/%s/public" % (prepath, user) ## path = "/%s/hub/%s/public" % (prepath, user) parts = [(path, path)] for part in filename.split("/")[:]: path += "/" + part parts.append((path, part)) breadcrumbs = " / ".join(map(lambda pair: '<a href="%s" target="_blank">%s</a>' % pair, parts)) ## # could be: images, images/, images/subdir, images/subdir/ if not filename.endswith("/") and filename.strip() != "": filename += "/" files = glob.glob("/home/%s/public_html/%s*" % (user, filename)) self.write("<h1>Jupyter Project at Bryn Mawr College</h1>\n") self.write("[<a href=\"/jupyter/hub/login\">Home</a>] ") if self.get_current_user_name(): self.write("[<a href=\"/user/%(current_user)s/tree\">%(current_user)s</a>] " % {"current_user": self.get_current_user_name()}) self.write("<p/>\n") self.write("<p>Public notebooks: %s </p>\n" % breadcrumbs) self.write("<ol>\n") for absolute_filename in sorted(files): if os.path.isdir(absolute_filename): dir_path = absolute_filename.split("/") dir_name = dir_path[-1] public_path = "/".join(dir_path[dir_path.index("public_html") + 1:]) self.write("<li><a href=\"%(url_path)s/%(public_path)s\">%(dir_name)s</a></li>\n" % {"url_path": url_path, "dir_name": dir_name, "public_path": public_path}) else: file_path, filename = absolute_filename.rsplit("/", 1) dir_path = absolute_filename.split("/") public_path = "/".join(dir_path[dir_path.index("public_html") + 1:]) variables = {"user": user, "filename": filename, "url_path": url_path, "next": next, "public_path": public_path} if filename.endswith(".ipynb"): if self.get_current_user_name(): self.write(("<li><a href=\"%(url_path)s/%(public_path)s\">%(filename)s</a> "+ #"(<a href=\"%(url_path)s/%(public_path)s?raw\">raw</a>, " + "(<a href=\"%(url_path)s/%(public_path)s?download\">download</a>" + #"<a href=\"%(url_path)s/%(public_path)s?copy\">copy</a>" + #((", <a href=\"/user/%s/notebooks/public_html/%s\">edit</a>" % (user, filename)) if self.get_current_user_name() == user else ", edit") + ")</li>\n") % variables) else: self.write(("<li><a href=\"%(url_path)s/%(public_path)s\">%(filename)s</a> "+ #"(<a href=\"%(url_path)s/%(public_path)s?raw\">raw</a>, " + "(<a href=\"%(url_path)s/%(public_path)s?download\">download</a>)" + #"copy, edit) " + #"[<a href=\"/jupyter/hub/login?next=%(next)s\">login</a> to copy]</li>\n") % variables) "</li>\n") % variables) else: # some other kind of file (eg, .zip, .css): self.write("<li><a href=\"%(url_path)s/%(public_path)s\">%(filename)s</a></li>\n" % variables) self.write("</ol>\n") self.write("<hr>\n") self.write("<p><i>Please see <a href=\"/jupyter/hub/dblank/public/Jupyter Help.ipynb\">Jupyter Help</a> for more information about this server.</i></p>\n")
def notebook(preprocessor, tag, markup): match = FORMAT.search(markup) if match: argdict = match.groupdict() src = argdict['src'] start = argdict['start'] end = argdict['end'] language = argdict['language'] else: raise ValueError("Error processing input, " "expected syntax: {0}".format(SYNTAX)) if start: start = int(start) else: start = 0 if end: end = int(end) else: end = None language_applied_highlighter = partial(custom_highlighter, language=language) nb_dir = preprocessor.configs.getConfig('NOTEBOOK_DIR') nb_path = os.path.join('content', nb_dir, src) if not os.path.exists(nb_path): raise ValueError("File {0} could not be found".format(nb_path)) # Create the custom notebook converter c = Config({'CSSHTMLHeaderTransformer': {'enabled':True, 'highlight_class':'.highlight-ipynb'}, 'SubCell': {'enabled':True, 'start':start, 'end':end}}) template_file = 'basic' if IPYTHON_VERSION >= 3: if os.path.exists('pelicanhtml_3.tpl'): template_file = 'pelicanhtml_3' elif IPYTHON_VERSION == 2: if os.path.exists('pelicanhtml_2.tpl'): template_file = 'pelicanhtml_2' else: if os.path.exists('pelicanhtml_1.tpl'): template_file = 'pelicanhtml_1' if IPYTHON_VERSION >= 2: subcell_kwarg = dict(preprocessors=[SubCell]) else: subcell_kwarg = dict(transformers=[SubCell]) exporter = HTMLExporter(config=c, template_file=template_file, filters={'highlight2html': language_applied_highlighter}, **subcell_kwarg) # read and parse the notebook with open(nb_path, encoding="utf-8") as f: nb_text = f.read() if IPYTHON_VERSION < 3: nb_json = IPython.nbformat.current.reads_json(nb_text) else: try: nb_json = nbformat.reads(nb_text, as_version=4) except: nb_json = IPython.nbformat.reads(nb_text, as_version=4) (body, resources) = exporter.from_notebook_node(nb_json) # if we haven't already saved the header, save it here. if not notebook.header_saved: print ("\n ** Writing styles to _nb_header.html: " "this should be included in the theme. **\n") header = '\n'.join(CSS_WRAPPER.format(css_line) for css_line in resources['inlining']['css']) header += JS_INCLUDE with open('_nb_header.html', 'w', encoding="utf-8") as f: f.write(header) notebook.header_saved = True # this will stash special characters so that they won't be transformed # by subsequent processes. body = preprocessor.configs.htmlStash.store(body, safe=True) return body