From 6e8e0573bab7afa0e422520422c2a2eb706016c1 2013-05-17 18:32:42 From: Jonathan Frederic Date: 2013-05-17 18:32:42 Subject: [PATCH] Cleanup and refactor, transformers --- diff --git a/nbconvert/transformers/activatable.py b/nbconvert/transformers/activatable.py index 662295a..df7cee4 100755 --- a/nbconvert/transformers/activatable.py +++ b/nbconvert/transformers/activatable.py @@ -1,19 +1,53 @@ +""" +Contains base transformer with an enable/disable flag. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + from .base import ConfigurableTransformer from IPython.utils.traitlets import (Bool) -class ActivatableTransformer(ConfigurableTransformer): - """A simple ConfigurableTransformers that have an enabled flag +#----------------------------------------------------------------------------- +# Classes and Functions +#----------------------------------------------------------------------------- - Inherit from that if you just want to have a transformer which is - no-op by default but can be activated in profiles with +class ActivatableTransformer(ConfigurableTransformer): + """ConfigurableTransformer that has an enabled flag - c.YourTransformerName.enabled = True + Inherit from this if you just want to have a transformer which is + enabled by default and can be disabled via the config by + 'c.YourTransformerName.enabled = True' """ enabled = Bool(True, config=True) - def __call__(self, nb, other): + def __call__(self, nb, resources): + """ + Transformation to apply on each notebook. + + You should return modified nb, resources. + If you wish to apply your transform on each cell, you might want to + overwrite cell_transform method instead. + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + """ + if not self.enabled : - return nb, other + return nb, resources else : - return super(ActivatableTransformer, self).__call__(nb, other) + return super(ActivatableTransformer, self).__call__(nb, resources) diff --git a/nbconvert/transformers/base.py b/nbconvert/transformers/base.py index a25a325..cee6797 100755 --- a/nbconvert/transformers/base.py +++ b/nbconvert/transformers/base.py @@ -1,15 +1,29 @@ """ -Module that regroups transformer that woudl be applied to ipynb files +Module that re-groups transformer that would be applied to iPyNB files before going through the templating machinery. -It exposes convenient classes to inherit from to access configurability -as well as decorator to simplify tasks. +It exposes a convenient class to inherit from to access configurability. """ +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- from __future__ import print_function, absolute_import from IPython.config.configurable import Configurable +#----------------------------------------------------------------------------- +# Classes and Functions +#----------------------------------------------------------------------------- + class ConfigurableTransformer(Configurable): """ A configurable transformer @@ -21,39 +35,65 @@ class ConfigurableTransformer(Configurable): you can overwrite cell_transform to apply a transformation independently on each cell or __call__ if you prefer your own logic. See orresponding docstring for informations. - - """ def __init__(self, config=None, **kw): + """ + Public constructor + + Parameters + ---------- + config : Config + Configuration file structure + **kw : misc + Additional arguments + """ + super(ConfigurableTransformer, self).__init__(config=config, **kw) - def __call__(self, nb, other): - """transformation to apply on each notebook. - - received a handle to the current notebook as well as a dict of resources - which structure depends on the transformer. - You should return modified nb, other. - - If you wish to apply on each cell, you might want to overwrite cell_transform method. + def __call__(self, nb, resources): + """ + Transformation to apply on each notebook. + + You should return modified nb, resources. + If you wish to apply your transform on each cell, you might want to + overwrite cell_transform method instead. + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. """ try : for worksheet in nb.worksheets : for index, cell in enumerate(worksheet.cells): - worksheet.cells[index], other = self.cell_transform(cell, other, 100*index) - return nb, other + + #TODO: Why are we multiplying the index by 100 here??? + worksheet.cells[index], resources = self.cell_transform(cell, resources, 100*index) + return nb, resources except NotImplementedError: raise NotImplementedError('should be implemented by subclass') - def cell_transform(self, cell, other, index): - """ - Overwrite if you want to apply a transformation on each cell, - receive the current cell, the resource dict and the index of current cell as parameter. - - You should return modified cell and resource dict. + def cell_transform(self, cell, resources, index): + """ + Overwrite if you want to apply a transformation on each cell. You + should return modified cell and resource dictionary. + + Parameters + ---------- + cell : NotebookNode cell + Notebook cell being processed + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Index of the cell being processed """ raise NotImplementedError('should be implemented by subclass') - return cell, other + return cell, resources diff --git a/nbconvert/transformers/coalescestreams.py b/nbconvert/transformers/coalescestreams.py index b81ba68..1edfc25 100644 --- a/nbconvert/transformers/coalescestreams.py +++ b/nbconvert/transformers/coalescestreams.py @@ -1,33 +1,66 @@ +"""Module that allows latex output notebooks to be conditioned before +they are converted. Exposes a decorator (@cell_preprocessor) in +addition to the coalesce_streams pre-proccessor. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- -def cell_preprocessor(function): - """ wrap a function to be executed on all cells of a notebook +#----------------------------------------------------------------------------- +# Functions +#----------------------------------------------------------------------------- -wrapped function parameters : -cell : the cell -other : external resources -index : index of the cell -""" - def wrappedfunc(nb, other): +def cell_preprocessor(function): + """ + Wrap a function to be executed on all cells of a notebook + + Wrapped Parameters + ---------- + cell : NotebookNode cell + Notebook cell being processed + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Index of the cell being processed + """ + + def wrappedfunc(nb, resources): for worksheet in nb.worksheets : for index, cell in enumerate(worksheet.cells): - worksheet.cells[index], other = function(cell, other, index) - return nb, other + worksheet.cells[index], resources = function(cell, resources, index) + return nb, resources return wrappedfunc @cell_preprocessor -def coalesce_streams(cell, other, count): - """merge consecutive sequences of stream output into single stream - -to prevent extra newlines inserted at flush calls - -TODO: handle \r deletion -""" +def coalesce_streams(cell, resources, index): + """ + Merge consecutive sequences of stream output into single stream + to prevent extra newlines inserted at flush calls + + Parameters + ---------- + cell : NotebookNode cell + Notebook cell being processed + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Index of the cell being processed + """ + outputs = cell.get('outputs', []) if not outputs: - return cell, other + return cell, resources + last = outputs[0] new_outputs = [last] + for output in outputs[1:]: if (output.output_type == 'stream' and last.output_type == 'stream' and @@ -38,5 +71,5 @@ TODO: handle \r deletion new_outputs.append(output) cell.outputs = new_outputs - return cell, other + return cell, resources diff --git a/nbconvert/transformers/csshtmlheader.py b/nbconvert/transformers/csshtmlheader.py index 31763d4..f735412 100755 --- a/nbconvert/transformers/csshtmlheader.py +++ b/nbconvert/transformers/csshtmlheader.py @@ -1,57 +1,119 @@ +"""Module that pre-processes the notebook for export to HTML. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import io + +from pygments.formatters import HtmlFormatter + +from IPython.utils import path + from .activatable import ActivatableTransformer + +#----------------------------------------------------------------------------- +# Classes and functions +#----------------------------------------------------------------------------- class CSSHtmlHeaderTransformer(ActivatableTransformer): + """ + Transformer used to pre-process notebook for HTML output. Adds IPython notebook + front-end CSS and Pygments CSS to HTML output. + """ - def __call__(self, nb, resources): - """Fetch and add css to the resource dict + header = [] - Fetch css from IPython adn Pygment to add at the beginning - of the html files. + def __init__(self, config=None, **kw): + """ + Public constructor + + Parameters + ---------- + config : Config + Configuration file structure + **kw : misc + Additional arguments + """ + + super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw) - Add this css in resources in the "inlining.css" key + if self.enabled : + self._regen_header() + + + def __call__(self, nb, resources): + """Fetch and add CSS to the resource dictionary + + Fetch CSS from IPython and Pygments to add at the beginning + of the html files. Add this css in resources in the + "inlining.css" key + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. """ + resources['inlining'] = {} resources['inlining']['css'] = self.header + return nb, resources - header = [] - def __init__(self, config=None, **kw): - super(CSSHtmlHeaderTransformer, self).__init__(config=config, **kw) - if self.enabled : - self.regen_header() - - def regen_header(self): - ## lazy load asa this might not be use in many transformers - import os - from IPython.utils import path - import io - from pygments.formatters import HtmlFormatter + def _regen_header(self): + """ + Fills self.header with lines of CSS extracted from iPython + and Pygments. + """ + + #Clear existing header. header = [] - static = os.path.join(path.get_ipython_package_dir(), - 'frontend', 'html', 'notebook', 'static', - ) + + #Construct path to iPy CSS + static = os.path.join(path.get_ipython_package_dir(), 'frontend', + 'html', 'notebook', 'static') css = os.path.join(static, 'css') + + #Load each known CSS file. for sheet in [ - # do we need jquery and prettify? + # TODO: do we need jquery and prettify? # os.path.join(static, 'jquery', 'css', 'themes', 'base', # 'jquery-ui.min.css'), # os.path.join(static, 'prettify', 'prettify.css'), + os.path.join(css, 'boilerplate.css'), os.path.join(css, 'fbm.css'), os.path.join(css, 'notebook.css'), os.path.join(css, 'renderedhtml.css'), os.path.join(css, 'style.min.css'), - ]: + ]: + try: - with io.open(sheet, encoding='utf-8') as f: - s = f.read() - header.append(s) + with io.open(sheet, encoding='utf-8') as file: + file_text = file.read() + header.append(file_text) except IOError: - # new version of ipython with style.min.css, pass + + # New version of iPython with style.min.css, pass pass + #Add pygments CSS pygments_css = HtmlFormatter().get_style_defs('.highlight') header.append(pygments_css) + + #Set header self.header = header diff --git a/nbconvert/transformers/extractfigure.py b/nbconvert/transformers/extractfigure.py index 29cfaef..16270eb 100755 --- a/nbconvert/transformers/extractfigure.py +++ b/nbconvert/transformers/extractfigure.py @@ -1,66 +1,127 @@ +"""Module containing a transformer that extracts all of the figures from the +notebook file. The extracted figures are returned in the 'resources' dictionary. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + from IPython.utils.traitlets import (Dict, List, Unicode) from .activatable import ActivatableTransformer +#----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +FIGURES_KEY = "figures" +BINARY_KEY = "binary" +TEXT_KEY = "text" + +#----------------------------------------------------------------------------- +# Classes +#----------------------------------------------------------------------------- + class ExtractFigureTransformer(ActivatableTransformer): + """ + Extracts all of the figures from the notebook file. The extracted + figures are returned in the 'resources' dictionary. + """ + + extra_extension_map = Dict({}, + config=True, + help="""Extra map to override extension based on type. + Useful for latex where SVG will be converted to PDF before inclusion + """) + + key_format_map = Dict({}, config=True,) + figure_name_format_map = Dict({}, config=True) + display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text']) - extra_ext_map = Dict({}, - config=True, - help="""extra map to override extension based on type. - Usefull for latex where svg will be converted to pdf before inclusion - """ - ) + #TODO: Change this to .format {} syntax + default_key_template = Unicode('_fig_{count:02d}.{ext}', config=True) - key_format_map = Dict({}, - config=True, - ) + def cell_transform(self, cell, resources, index): + """ + Apply a transformation on each cell, + + Parameters + ---------- + cell : NotebookNode cell + Notebook cell being processed + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Modified index of the cell being processed (see base.py) + """ + + if resources.get(FIGURES_KEY, None) is None : + resources[FIGURES_KEY] = {TEXT_KEY:{},BINARY_KEY:{}} + + for out in cell.get('outputs', []): + for out_type in self.display_data_priority: + + if out.hasattr(out_type): + figname, key, data, binary = self._new_figure(out[out_type], out_type, index) + out['key_'+out_type] = figname + + if binary : + resources[FIGURES_KEY][BINARY_KEY][key] = data + else : + resources[FIGURES_KEY][TEXT_KEY][key] = data + + index += 1 + return cell, resources - figname_format_map = Dict({}, - config=True, - ) - display_data_priority = List(['svg', 'png', 'latex', 'jpg', 'jpeg','text']) + def _get_override_extension(self, extension): + """Gets the overriden extension if it exists, else returns extension. - #to do change this to .format {} syntax - default_key_tpl = Unicode('_fig_{count:02d}.{ext}', config=True) + Parameters + ---------- + extension : str + File extension. + """ + + if extension in self.extra_extension_map : + return self.extra_extension_map[extension] + + return extension - def _get_ext(self, ext): - if ext in self.extra_ext_map : - return self.extra_ext_map[ext] - return ext - def _new_figure(self, data, fmt, count): + def _new_figure(self, data, format, index): """Create a new figure file in the given format. + Parameters + ---------- + data : str + Cell data (from Notebook node cell) + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Modified index of the cell being processed (see base.py) """ - tplf = self.figname_format_map.get(fmt, self.default_key_tpl) - tplk = self.key_format_map.get(fmt, self.default_key_tpl) + + figure_name_template = self.figure_name_format_map.get(format, self.default_key_template) + key_template = self.key_format_map.get(format, self.default_key_template) - # option to pass the hash as data ? - figname = tplf.format(count=count, ext=self._get_ext(fmt)) - key = tplk.format(count=count, ext=self._get_ext(fmt)) + #TODO: option to pass the hash as data? + figure_name = figure_name_template.format(index=index, ext=self._get_override_extension(format)) + key = key_template.format(index=index, ext=self._get_override_extension(format)) - # Binary files are base64-encoded, SVG is already XML + #Binary files are base64-encoded, SVG is already XML binary = False - if fmt in ('png', 'jpg', 'pdf'): + if format in ('png', 'jpg', 'pdf'): data = data.decode('base64') binary = True - return figname, key, data, binary - - - def cell_transform(self, cell, other, count): - if other.get('figures', None) is None : - other['figures'] = {'text':{},'binary':{}} - for out in cell.get('outputs', []): - for out_type in self.display_data_priority: - if out.hasattr(out_type): - figname, key, data, binary = self._new_figure(out[out_type], out_type, count) - out['key_'+out_type] = figname - if binary : - other['figures']['binary'][key] = data - else : - other['figures']['text'][key] = data - count = count+1 - return cell, other - + return figure_name, key, data, binary diff --git a/nbconvert/transformers/latex.py b/nbconvert/transformers/latex.py index 77820b5..a3d3c97 100755 --- a/nbconvert/transformers/latex.py +++ b/nbconvert/transformers/latex.py @@ -1,6 +1,4 @@ -"""Latex transformer. - -Module that allows latex output notebooks to be conditioned before +"""Module that allows latex output notebooks to be conditioned before they are converted. """ #----------------------------------------------------------------------------- @@ -14,6 +12,7 @@ they are converted. #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- + from __future__ import print_function, absolute_import # Our own imports @@ -24,20 +23,31 @@ from nbconvert.filters import latex #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- + class LatexTransformer(ActivatableTransformer): """ Converter for latex destined documents. """ - def cell_transform(self, cell, other, index): + def cell_transform(self, cell, resources, index): """ Apply a transformation on each cell, - - receive the current cell, the resource dict and the index of current cell as parameter. - - Returns modified cell and resource dict. + + Parameters + ---------- + cell : NotebookNode cell + Notebook cell being processed + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + index : int + Modified index of the cell being processed (see base.py) """ + #If the cell is a markdown cell, preprocess the ampersands used to + #remove the space between them and their contents. Latex will complain + #if spaces exist between the ampersands and the math content. + #See filters.latex.rm_math_space for more information. if hasattr(cell, "source") and cell.cell_type == "markdown": cell.source = latex.rm_math_space(cell.source) - return cell, other + return cell, resources diff --git a/nbconvert/transformers/revealhelp.py b/nbconvert/transformers/revealhelp.py index 76040f2..0755a10 100755 --- a/nbconvert/transformers/revealhelp.py +++ b/nbconvert/transformers/revealhelp.py @@ -1,12 +1,48 @@ +"""Module that pre-processes the notebook for export via Reveal. +""" +#----------------------------------------------------------------------------- +# Copyright (c) 2013, the IPython Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +#----------------------------------------------------------------------------- + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + from .base import ConfigurableTransformer +#----------------------------------------------------------------------------- +# Classes and functions +#----------------------------------------------------------------------------- + class RevealHelpTransformer(ConfigurableTransformer): - def __call__(self, nb, other): + def __call__(self, nb, resources): + """ + Called once to 'transform' contents of the notebook. + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + """ + + for worksheet in nb.worksheets : for i, cell in enumerate(worksheet.cells): + + #Make sure the cell has metadata. if not cell.get('metadata', None): break + + #Get the slide type. If type is start of subslide or slide, + #end the last subslide/slide. cell.metadata.slide_type = cell.metadata.get('slideshow', {}).get('slide_type', None) if cell.metadata.slide_type is None: cell.metadata.slide_type = '-' @@ -14,4 +50,6 @@ class RevealHelpTransformer(ConfigurableTransformer): worksheet.cells[i - 1].metadata.slide_helper = 'slide_end' if cell.metadata.slide_type in ['subslide']: worksheet.cells[i - 1].metadata.slide_helper = 'subslide_end' - return nb, other \ No newline at end of file + + return nb, resources + \ No newline at end of file diff --git a/nbconvert/transformers/sphinx.py b/nbconvert/transformers/sphinx.py index 200fb20..313f522 100755 --- a/nbconvert/transformers/sphinx.py +++ b/nbconvert/transformers/sphinx.py @@ -1,5 +1,6 @@ """Module that allows custom Sphinx parameters to be set on the notebook and -on the 'other' object passed into Jinja. +on the 'other' object passed into Jinja. Called prior to Jinja conversion +process. """ #----------------------------------------------------------------------------- # Copyright (c) 2013, the IPython Development Team. @@ -12,6 +13,7 @@ on the 'other' object passed into Jinja. #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- + from __future__ import print_function, absolute_import # Stdlib imports @@ -19,9 +21,6 @@ from __future__ import print_function, absolute_import import sphinx import os.path -# Used to determine python version -import sys - # Used to set the default date to today's date from datetime import date @@ -36,9 +35,12 @@ from IPython.utils.traitlets import Unicode, Bool # Needed to override transformer from .activatable import (ActivatableTransformer) #TODO +import nbconvert.utils.console + #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- + class SphinxTransformer(ActivatableTransformer): """ Sphinx utility transformer. @@ -48,73 +50,99 @@ class SphinxTransformer(ActivatableTransformer): """ interactive = Bool(True, config=True, help=""" - Allows you to define whether or not the Sphinx exporter will prompt - you for input during the conversion process. If this is set to false, - the author, version, release, date, and chapter_style traits should - be set. - """) + Allows you to define whether or not the Sphinx exporter will prompt + you for input during the conversion process. If this is set to false, + the author, version, release, date, and chapter_style traits should + be set. + """) author = Unicode("Unknown Author", config=True, help="Author name") - version = Unicode("", config=True, help="""Version number - You can leave this blank if you do not want to render a version number. - Example: "1.0.0" - """) + version = Unicode("", config=True, help=""" + Version number + You can leave this blank if you do not want to render a version number. + Example: "1.0.0" + """) - release = Unicode("", config=True, help="""Release name - You can leave this blank if you do not want to render a release name. - Example: "Rough Draft" - """) + release = Unicode("", config=True, help=""" + Release name + You can leave this blank if you do not want to render a release name. + Example: "Rough Draft" + """) - publish_date = Unicode("", config=True, help="""Publish date - This is the date to render on the document as the publish date. - Leave this blank to default to todays date. - Example: "June 12, 1990" - """) + publish_date = Unicode("", config=True, help=""" + Publish date + This is the date to render on the document as the publish date. + Leave this blank to default to todays date. + Example: "June 12, 1990" + """) - chapter_style = Unicode("Bjarne", config=True, help="""Sphinx chapter style - This is the style to use for the chapter headers in the document. - You may choose one of the following: - "Bjarne" (default) - "Lenny" - "Glenn" - "Conny" - "Rejne" - "Sonny" (used for international documents) - """) + chapter_style = Unicode("Bjarne", config=True, help=""" + Sphinx chapter style + This is the style to use for the chapter headers in the document. + You may choose one of the following: + "Bjarne" (default) + "Lenny" + "Glenn" + "Conny" + "Rejne" + "Sonny" (used for international documents) + """) - output_style = Unicode("notebook", config=True, help="""Nbconvert Ipython - notebook input/output formatting style. - You may choose one of the following: - "simple (recommended for long code segments)" - "notebook" (default) - """) + output_style = Unicode("notebook", config=True, help=""" + Nbconvert Ipython + notebook input/output formatting style. + You may choose one of the following: + "simple (recommended for long code segments)" + "notebook" (default) + """) center_output = Bool(False, config=True, help=""" - Optional attempt to center all output. If this is false, no additional - formatting is applied. - """) + Optional attempt to center all output. If this is false, no additional + formatting is applied. + """) use_headers = Bool(True, config=True, help=""" - Whether not a header should be added to the document. - """) + Whether not a header should be added to the document. + """) + #Allow the user to override the title of the notebook (useful for + #fancy document titles that the file system doesn't support.) overridetitle = Unicode("", config=True, help="") + - def __call__(self, nb, other): + def __call__(self, nb, resources): """ - Entry + Entrypoint Since we are not interested in any additional manipulation on a cell by cell basis, we do not call the base implementation. - """ + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. + """ + if self.enabled: - return self.transform(nb, other) + return self.transform(nb, resources) else: - return nb,other + return nb,resources + - def transform(self, nb, other): + def transform(self, nb, resources): """ Sphinx transformation to apply on each notebook. + + Parameters + ---------- + nb : NotebookNode + Notebook being converted + resources : dictionary + Additional resources used in the conversion process. Allows + transformers to pass variables into the Jinja engine. """ # TODO: Add versatile method of additional notebook metadata. Include @@ -123,8 +151,8 @@ class SphinxTransformer(ActivatableTransformer): if not "_draft" in nb.metadata: nb.metadata._draft = {} - if not "sphinx" in other: - other["sphinx"] = {} + if not "sphinx" in resources: + resources["sphinx"] = {} if self.interactive: @@ -136,12 +164,12 @@ class SphinxTransformer(ActivatableTransformer): nb.metadata._draft["date"] = self._prompt_date() # Prompt the user for the document style. - other["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style() - other["sphinx"]["outputstyle"] = self._prompt_output_style() + resources["sphinx"]["chapterstyle"] = self._prompt_chapter_title_style() + resources["sphinx"]["outputstyle"] = self._prompt_output_style() # Small options - other["sphinx"]["centeroutput"] = self._prompt_boolean("Do you want to center the output? (false)", False) - other["sphinx"]["header"] = self._prompt_boolean("Should a Sphinx document header be used? (true)", True) + resources["sphinx"]["centeroutput"] = nbconvert.utils.console.prompt_boolean("Do you want to center the output? (false)", False) + resources["sphinx"]["header"] = nbconvert.utils.console.prompt_boolean("Should a Sphinx document header be used? (true)", True) else: # Try to use the traitlets. @@ -156,58 +184,71 @@ class SphinxTransformer(ActivatableTransformer): nb.metadata._draft["date"] = self.publish_date # Sphinx traitlets. - other["sphinx"]["chapterstyle"] = self.chapter_style - other["sphinx"]["outputstyle"] = self.output_style - other["sphinx"]["centeroutput"] = self.center_output - other["sphinx"]["header"] = self.use_headers + resources["sphinx"]["chapterstyle"] = self.chapter_style + resources["sphinx"]["outputstyle"] = self.output_style + resources["sphinx"]["centeroutput"] = self.center_output + resources["sphinx"]["header"] = self.use_headers # Find and pass in the path to the Sphinx dependencies. - other["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs") + resources["sphinx"]["texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs") # Generate Pygments definitions for Latex - other["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def() + resources["sphinx"]["pygment_definitions"] = self._generate_pygments_latex_def() if not (self.overridetitle == None or len(self.overridetitle.strip()) == 0): nb.metadata.name = self.overridetitle # End - return nb, other + return nb, resources + def _generate_pygments_latex_def(self): + """ + Generate the pygments latex definitions that allows pygments + to work in latex. + """ + return LatexFormatter().get_style_defs() + def _prompt_author(self): - return self._input("Author name: ") + """ + Prompt the user to input an Author name + """ + return nbconvert.utils.console.input("Author name: ") + def _prompt_version(self): - return self._input("Version (ie ""1.0.0""): ") + """ + prompt the user to enter a version number + """ + return nbconvert.utils.console.input("Version (ie ""1.0.0""): ") + def _prompt_release(self): - return self._input("Release Name (ie ""Rough draft""): ") + """ + Prompt the user to input a release name + """ + + return nbconvert.utils.console.input("Release Name (ie ""Rough draft""): ") + def _prompt_date(self): + """ + Prompt the user to enter a date + """ + default_date = date.today().strftime("%B %-d, %Y") - user_date = self._input("Date (deafults to \"" + default_date + "\"): ") + user_date = nbconvert.utils.console.input("Date (deafults to \"" + default_date + "\"): ") if len(user_date.strip()) == 0: user_date = default_date return user_date - def _prompt_boolean(self, prompt, default=False): - response = self._input(prompt) - response = response.strip().lower() - - #Catch 1, true, yes as True - if len(response) > 0 and (response == "1" or response[0] == "t" or response[0] == "y"): - return True - - #Catch 0, false, no as False - elif len(response) > 0 and (response == "0" or response[0] == "f" or response[0] == "n"): - return False - - else: - return default - + def _prompt_output_style(self): + """ + Prompts the user to pick an iPython output style. + """ # Dictionary of available output styles styles = {1: "simple", @@ -217,9 +258,13 @@ class SphinxTransformer(ActivatableTransformer): comments = {1: "(recommended for long code segments)", 2: "(default)"} - return self._prompt_dictionary(styles, default_style=2, menu_comments=comments) + return nbconvert.utils.console.prompt_dictionary(styles, default_style=2, menu_comments=comments) + def _prompt_chapter_title_style(self): + """ + Prompts the user to pick a Sphinx chapter style + """ # Dictionary of available Sphinx styles styles = {1: "Bjarne", @@ -233,55 +278,5 @@ class SphinxTransformer(ActivatableTransformer): comments = {1: "(default)", 6: "(for international documents)"} - return self._prompt_dictionary(styles, menu_comments=comments) - - def _prompt_dictionary(self, choices, default_style=1, menu_comments={}): - - # Build the menu that will be displayed to the user with - # all of the options available. - prompt = "" - for key, value in choices.iteritems(): - prompt += "%d %s " % (key, value) - if key in menu_comments: - prompt += menu_comments[key] - prompt += "\n" - - # Continue to ask the user for a style until an appropriate - # one is specified. - response = -1 - while (not response in choices): - try: - text_response = self._input(prompt) - - # Use default option if no input. - if len(text_response.strip()) == 0: - response = default_style - else: - response = int(text_response) - except: - print("Error: Value is not an available option. 0 selects the default.\n") - return choices[response] - - def _input(self, prompt_text): - """ - Prompt the user for input. - - The input command will change depending on the version of python - installed. To maintain support for 2 and earlier, we must use - raw_input in that case. Else use input. - """ - - # Try to get the python version. This command is only available in - # python 2 and later, so it's important that we catch the exception - # if the command isn't found. - try: - majorversion = sys.version_info[0] - except: - majorversion = 1 - - # Use the correct function to prompt the user for input depending on - # what python version the code is running in. - if majorversion >= 3: - return input(prompt_text) - else: - return raw_input(prompt_text) + return nbconvert.utils.console.prompt_dictionary(styles, menu_comments=comments) + \ No newline at end of file