__init__.py
150 lines
| 4.8 KiB
| text/x-python
|
PythonLexer
slojo404
|
r6232 | """ | ||
Simple ipython notebook document tree Writer. | ||||
""" | ||||
__docformat__ = 'reStructuredText' | ||||
import sys | ||||
import os | ||||
import os.path | ||||
import time | ||||
import re | ||||
import urllib | ||||
import docutils | ||||
from docutils import frontend, nodes, utils, writers, languages, io | ||||
from docutils.transforms import writer_aux | ||||
Matthias BUSSONNIER
|
r9898 | try: | ||
from docutils.math import unichar2tex, pick_math_environment | ||||
from docutils.math.latex2mathml import parse_latex_math | ||||
from docutils.math.math2html import math2html | ||||
except ImportError: | ||||
from docutils.utils.math import unichar2tex, pick_math_environment | ||||
from docutils.utils.math.latex2mathml import parse_latex_math | ||||
from docutils.utils.math.math2html import math2html | ||||
Matthias BUSSONNIER
|
r9897 | |||
try: | ||||
from docutils.utils.error_reporting import SafeString | ||||
except ImportError: | ||||
from docutils.error_reporting import SafeString | ||||
slojo404
|
r6232 | from IPython.nbformat import current as nbformat | ||
Valentin Haenel
|
r9359 | import pypandoc | ||
slojo404
|
r6232 | |||
Valentin Haenel
|
r9326 | # the ipython prompt regular expression | ||
Valentin Haenel
|
r9359 | IPYPROMPT = re.compile(r"(?P<prompt>In \[[0-9]+\]:)(?P<code>.*)") | ||
slojo404
|
r6232 | |||
slojo404
|
r6277 | |||
slojo404
|
r6232 | class Writer(writers.Writer): | ||
supported = ('ipynb') | ||||
"""Formats this writer supports.""" | ||||
slojo404
|
r6277 | |||
slojo404
|
r6232 | visitor_attributes = () | ||
def get_transforms(self): | ||||
return writers.Writer.get_transforms(self) + [writer_aux.Admonitions] | ||||
def __init__(self): | ||||
writers.Writer.__init__(self) | ||||
self.translator_class = IPYNBTranslator | ||||
def translate(self): | ||||
self.visitor = visitor = self.translator_class(self.document) | ||||
self.document.walkabout(visitor) | ||||
for attr in self.visitor_attributes: | ||||
setattr(self, attr, getattr(visitor, attr)) | ||||
slojo404
|
r6281 | self.output = '{0}'.format(nbformat.writes(visitor.nb, 'ipynb')) | ||
slojo404
|
r6232 | |||
Paul Ivanov
|
r6283 | class IPYNBTranslator(nodes.GenericNodeVisitor): | ||
slojo404
|
r6232 | |||
""" | ||||
""" | ||||
def __init__(self, document): | ||||
nodes.NodeVisitor.__init__(self, document) | ||||
self.settings = settings = document.settings | ||||
lcode = settings.language_code | ||||
self.language = languages.get_language(lcode, document.reporter) | ||||
# A heterogenous stack used in conjunction with the tree traversal. | ||||
# Make sure that the pops correspond to the pushes: | ||||
self.context = [] | ||||
self.body = [] | ||||
slojo404
|
r6276 | self.section_level = 0 | ||
slojo404
|
r6232 | ws = nbformat.new_worksheet() | ||
self.nb = nbformat.new_notebook(worksheets=[ws]) | ||||
def astext(self): | ||||
slojo404
|
r6281 | return '{0}'.format(nbformat.writes(self.nb, 'ipynb')) | ||
slojo404
|
r6235 | |||
def is_ref_error_paragraph(self, p): | ||||
return p == "Unknown interpreted text role \"ref\"." | ||||
slojo404
|
r6277 | |||
slojo404
|
r6232 | def add_cell(self, cell): | ||
self.nb.worksheets[0].cells.append(cell) | ||||
Valentin Haenel
|
r9326 | def add_code_cell(self, lines): | ||
c = nbformat.new_code_cell(input='\n'.join(lines)) | ||||
self.add_cell(c) | ||||
slojo404
|
r6278 | def visit_literal_block(self, node): | ||
raw_text = node.astext() | ||||
Valentin Haenel
|
r9326 | current_cell = [] | ||
for line in raw_text.split('\n'): | ||||
ipyprompt = IPYPROMPT.match(line) | ||||
# try matching the >>> prompt | ||||
if line.startswith('>>>'): | ||||
current_cell.append(line.split('>>>')[1][1:]) | ||||
# try matching ipypromt | ||||
elif ipyprompt is not None: | ||||
current_cell.append(ipyprompt.groupdict()['code'].strip()) | ||||
# some kind of output | ||||
elif current_cell: | ||||
self.add_code_cell(current_cell) | ||||
current_cell = [] | ||||
# if the last line was not output | ||||
if current_cell: | ||||
self.add_code_cell(current_cell) | ||||
slojo404
|
r6278 | |||
slojo404
|
r6232 | def visit_paragraph(self, node): | ||
slojo404
|
r6235 | text = node.astext() | ||
# For every ref directive a paragraph contains | ||||
# docutils will generate a paragraph complaining | ||||
# "Unknown interpreted text role \"ref\"." | ||||
# this is because ref is a sphinx directive | ||||
# that does not exist in docutils | ||||
# looking for a better way to handle this | ||||
slojo404
|
r6277 | # for now filtering such pargraphs from the output | ||
slojo404
|
r6235 | |||
if not self.is_ref_error_paragraph(text): | ||||
p = nbformat.new_text_cell('markdown', source=text) | ||||
self.add_cell(p) | ||||
slojo404
|
r6232 | |||
def visit_section(self, node): | ||||
slojo404
|
r6276 | self.section_level += 1 | ||
slojo404
|
r6232 | self.default_visit(node) | ||
def depart_section(self, node): | ||||
slojo404
|
r6276 | self.section_level -= 1 | ||
Paul Ivanov
|
r6283 | self.default_departure(node) | ||
slojo404
|
r6232 | |||
slojo404
|
r6278 | def visit_title(self, node): | ||
#make sure we have a valid heading level between 1 and 6 | ||||
heading_level = min(self.section_level, 5) + 1 | ||||
h = nbformat.new_heading_cell(source=node.astext(), | ||||
level=heading_level) | ||||
self.add_cell(h) | ||||
slojo404
|
r6232 | |||
def default_visit(self, node): | ||||
node_class = node.__class__.__name__ | ||||
#print '*default_visit', node_class | ||||
slojo404
|
r6235 | #if node_class in ['reference','paragraph','literal_block','title']: | ||
if node_class in []: | ||||
print '*default_visit', node_class | ||||
print node.astext() | ||||
slojo404
|
r6232 | |||
Paul Ivanov
|
r6283 | def default_departure(self, node): | ||
slojo404
|
r6232 | #print '*default depart', node.__class__.__name__ | ||
pass | ||||