sphinx_transformer.py
200 lines
| 6.7 KiB
| text/x-python
|
PythonLexer
/ converters / sphinx_transformer.py
Jonathan Frederic
|
r9772 | """ | ||
Module that allows custom Sphinx parameters to be set on the notebook and | ||||
on the 'other' object passed into Jinja. | ||||
""" | ||||
Matthias BUSSONNIER
|
r9819 | from __future__ import absolute_import | ||
Jonathan Frederic
|
r9772 | |||
# Used to find Sphinx package location | ||||
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 | ||||
# Configurable traitlets | ||||
from IPython.utils.traitlets import Unicode, Bool | ||||
Jonathan Frederic
|
r9780 | # Needed for Pygments latex definitions. | ||
from pygments.formatters import LatexFormatter | ||||
Jonathan Frederic
|
r9772 | # Needed to override transformer | ||
Matthias BUSSONNIER
|
r9819 | from .transformers import (ActivatableTransformer) | ||
Jonathan Frederic
|
r9772 | |||
Jonathan Frederic
|
r9775 | class SphinxTransformer(ActivatableTransformer): | ||
Jonathan Frederic
|
r9772 | """ | ||
Sphinx utility transformer. | ||||
This transformer is used to set variables needed by the latex to build | ||||
Sphinx stylized templates. | ||||
""" | ||||
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 chapterstyle 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" | ||||
""") | ||||
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" | ||||
""") | ||||
publishdate = 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" | ||||
""") | ||||
chapterstyle = 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) | ||||
""") | ||||
def __call__(self, nb, other): | ||||
""" | ||||
Jonathan Frederic
|
r9775 | Entry | ||
Jonathan Frederic
|
r9772 | Since we are not interested in any additional manipulation on a cell | ||
by cell basis, we do not call the base implementation. | ||||
""" | ||||
Jonathan Frederic
|
r9775 | if self.enabled: | ||
Jonathan Frederic
|
r9778 | return self.transform(nb, other) | ||
Matthias BUSSONNIER
|
r9807 | else: | ||
return nb,other | ||||
Jonathan Frederic
|
r9772 | |||
Jonathan Frederic
|
r9778 | def transform(self, nb, other): | ||
Jonathan Frederic
|
r9775 | """ | ||
Sphinx transformation to apply on each notebook. | ||||
""" | ||||
Jonathan Frederic
|
r9772 | if self.interactive: | ||
# Prompt the user for additional meta data that doesn't exist currently | ||||
# but would be usefull for Sphinx. | ||||
nb.metadata["author"] = self._prompt_author() | ||||
nb.metadata["version"] = self._prompt_version() | ||||
nb.metadata["release"] = self._prompt_release() | ||||
nb.metadata["date"] = self._prompt_date() | ||||
# Prompt the user for the document style. | ||||
other["sphinx_chapterstyle"] = self._prompt_chapter_title_style() | ||||
else: | ||||
# Try to use the traitlets. | ||||
nb.metadata["author"] = self.author | ||||
nb.metadata["version"] = self.version | ||||
nb.metadata["release"] = self.release | ||||
if len(self.publishdate.strip()) == 0: | ||||
nb.metadata["date"] = date.today().strftime("%B %-d, %Y") | ||||
else: | ||||
nb.metadata["date"] = self.publishdate | ||||
other["sphinx_chapterstyle"] = self.chapterstyle | ||||
# Find and pass in the path to the Sphinx dependencies. | ||||
other["sphinx_texinputs"] = os.path.abspath(sphinx.__file__ + "/../texinputs") | ||||
Jonathan Frederic
|
r9780 | # Generate Pygments definitions for Latex | ||
other["pygment_definitions"] = self._generate_pygments_latex_def() | ||||
Jonathan Frederic
|
r9772 | # End | ||
Jonathan Frederic
|
r9780 | return nb, other | ||
def _generate_pygments_latex_def(self): | ||||
return LatexFormatter().get_style_defs() | ||||
Jonathan Frederic
|
r9772 | |||
def _prompt_author(self): | ||||
return self._input("Author name: ") | ||||
def _prompt_version(self): | ||||
return self._input("Version (ie ""1.0.0""): ") | ||||
def _prompt_release(self): | ||||
return self._input("Release Name (ie ""Rough draft""): ") | ||||
def _prompt_date(self): | ||||
default_date = date.today().strftime("%B %-d, %Y") | ||||
user_date = self._input("Date (deafults to \"" + default_date + "\"): ") | ||||
if len(user_date.strip()) == 0: | ||||
user_date = default_date | ||||
return user_date | ||||
def _prompt_chapter_title_style(self): | ||||
# Dictionary of available Sphinx styles | ||||
styles = {1: "Bjarne", | ||||
2: "Lenny", | ||||
3: "Glenn", | ||||
4: "Conny", | ||||
5: "Rejne", | ||||
6: "Sonny"} | ||||
default_style = 1 | ||||
# Build the menu that will be displayed to the user with | ||||
# all of the options available. | ||||
style_prompt = "" | ||||
for key, value in styles.iteritems(): | ||||
style_prompt += "%d %s" % (key, value) | ||||
if key == default_style: | ||||
style_prompt += " (default)" | ||||
elif value == "Sonny": | ||||
style_prompt += " (for international documents)" | ||||
style_prompt += "\n" | ||||
# Continue to ask the user for a style until an appropriate | ||||
# one is specified. | ||||
response = -1 | ||||
while (0 > response or response > 6): | ||||
try: | ||||
text_response = self._input(style_prompt) | ||||
# Use default option if no input. | ||||
if len(text_response.strip()) == 0: | ||||
response = 1 | ||||
else: | ||||
response = int(text_response) | ||||
except: | ||||
print("Error: Value must be a number between 1 and 6, leave blank for default\n") | ||||
return styles[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) | ||||