##// END OF EJS Templates
jupyter-rendering: added rendering of notebook into MarkupRenderer class.
marcink -
r1491:4811d677 default
parent child Browse files
Show More
@@ -38,6 +38,7 b' import string'
38 import hashlib
38 import hashlib
39 import pygments
39 import pygments
40 import itertools
40 import itertools
41 import fnmatch
41
42
42 from datetime import datetime
43 from datetime import datetime
43 from functools import partial
44 from functools import partial
@@ -1811,27 +1812,15 b' def urlify_commit_message(commit_text, r'
1811 return literal(newtext)
1812 return literal(newtext)
1812
1813
1813
1814
1814 def rst(source, mentions=False):
1815 return literal('<div class="rst-block">%s</div>' %
1816 MarkupRenderer.rst(source, mentions=mentions))
1817
1818
1819 def markdown(source, mentions=False):
1820 return literal('<div class="markdown-block">%s</div>' %
1821 MarkupRenderer.markdown(source, flavored=True,
1822 mentions=mentions))
1823
1824
1825 def renderer_from_filename(filename, exclude=None):
1815 def renderer_from_filename(filename, exclude=None):
1826 """
1816 """
1827 choose a renderer based on filename
1817 choose a renderer based on filename
1828 """
1818 """
1829
1819
1830 # images
1831
1832 # ipython
1820 # ipython
1833 if filename.endswith('.ipynb'):
1821 for ext in ['*.ipynb']:
1834 return 'ipython'
1822 if fnmatch.fnmatch(filename, pat=ext):
1823 return 'jupyter'
1835
1824
1836 is_markup = MarkupRenderer.renderer_from_filename(filename, exclude=exclude)
1825 is_markup = MarkupRenderer.renderer_from_filename(filename, exclude=exclude)
1837 if is_markup:
1826 if is_markup:
@@ -1841,26 +1830,18 b' def renderer_from_filename(filename, exc'
1841
1830
1842 def render(source, renderer='rst', mentions=False):
1831 def render(source, renderer='rst', mentions=False):
1843 if renderer == 'rst':
1832 if renderer == 'rst':
1844 return rst(source, mentions=mentions)
1833 return literal(
1834 '<div class="rst-block">%s</div>' %
1835 MarkupRenderer.rst(source, mentions=mentions))
1845 elif renderer == 'markdown':
1836 elif renderer == 'markdown':
1846 return markdown(source, mentions=mentions)
1837 return literal(
1847 elif renderer == 'ipython':
1838 '<div class="markdown-block">%s</div>' %
1848 def ipython_renderer(source):
1839 MarkupRenderer.markdown(source, flavored=True, mentions=mentions))
1849 import nbformat
1840 elif renderer == 'jupyter':
1850 from nbconvert import HTMLExporter
1841 return literal(
1851 notebook = nbformat.reads(source, as_version=4)
1842 '<div class="ipynb">%s</div>' %
1843 MarkupRenderer.jupyter(source))
1852
1844
1853 # 2. Instantiate the exporter. We use the `basic` template for now; we'll get into more details
1854 # later about how to customize the exporter further.
1855 html_exporter = HTMLExporter()
1856 html_exporter.template_file = 'basic'
1857
1858 # 3. Process the notebook we loaded earlier
1859 (body, resources) = html_exporter.from_notebook_node(notebook)
1860
1861 return body
1862
1863 return ipython_renderer(source)
1864 # None means just show the file-source
1845 # None means just show the file-source
1865 return None
1846 return None
1866
1847
@@ -29,6 +29,7 b' import logging'
29 import itertools
29 import itertools
30
30
31 from mako.lookup import TemplateLookup
31 from mako.lookup import TemplateLookup
32 from mako.template import Template as MakoTemplate
32
33
33 from docutils.core import publish_parts
34 from docutils.core import publish_parts
34 from docutils.parsers.rst import directives
35 from docutils.parsers.rst import directives
@@ -49,6 +50,7 b' class MarkupRenderer(object):'
49
50
50 MARKDOWN_PAT = re.compile(r'\.(md|mkdn?|mdown|markdown)$', re.IGNORECASE)
51 MARKDOWN_PAT = re.compile(r'\.(md|mkdn?|mdown|markdown)$', re.IGNORECASE)
51 RST_PAT = re.compile(r'\.re?st$', re.IGNORECASE)
52 RST_PAT = re.compile(r'\.re?st$', re.IGNORECASE)
53 JUPYTER_PAT = re.compile(r'\.(ipynb)$', re.IGNORECASE)
52 PLAIN_PAT = re.compile(r'^readme$', re.IGNORECASE)
54 PLAIN_PAT = re.compile(r'^readme$', re.IGNORECASE)
53
55
54 extensions = ['codehilite', 'extra', 'def_list', 'sane_lists']
56 extensions = ['codehilite', 'extra', 'def_list', 'sane_lists']
@@ -95,6 +97,8 b' class MarkupRenderer(object):'
95 detected_renderer = 'markdown'
97 detected_renderer = 'markdown'
96 elif MarkupRenderer.RST_PAT.findall(filename):
98 elif MarkupRenderer.RST_PAT.findall(filename):
97 detected_renderer = 'rst'
99 detected_renderer = 'rst'
100 elif MarkupRenderer.JUPYTER_PAT.findall(filename):
101 detected_renderer = 'jupyter'
98 elif MarkupRenderer.PLAIN_PAT.findall(filename):
102 elif MarkupRenderer.PLAIN_PAT.findall(filename):
99 detected_renderer = 'plain'
103 detected_renderer = 'plain'
100 else:
104 else:
@@ -263,6 +267,78 b' class MarkupRenderer(object):'
263 else:
267 else:
264 raise
268 raise
265
269
270 @classmethod
271 def jupyter(cls, source):
272 from rhodecode.lib import helpers
273 import nbformat
274 from nbconvert import HTMLExporter
275 from traitlets.config import Config
276
277 class CustomHTMLExporter(HTMLExporter):
278 def _template_file_default(self):
279 return 'basic'
280
281 def _sanitize_resources(resources):
282 """
283 Skip/sanitize some of the CSS generated and included in jupyter
284 so it doesn't messes up UI so much
285 """
286
287 # TODO(marcink): probably we should replace this with whole custom
288 # CSS set that doesn't screw up, but jupyter generated html has some
289 # special markers, so it requires Custom HTML exporter template with
290 # _default_template_path_default, to achieve that
291
292 # strip the reset CSS
293 resources[0] = resources[0][resources[0].find('/*! Source'):]
294 return resources
295
296 def as_html(notebook):
297 conf = Config()
298 html_exporter = CustomHTMLExporter(config=conf)
299
300 (body, resources) = html_exporter.from_notebook_node(notebook)
301 header = '<!-- ## IPYTHON NOTEBOOK RENDERING ## -->'
302 js = MakoTemplate(r'''
303 <!-- Load mathjax -->
304 <!-- MathJax configuration -->
305 <script type="text/x-mathjax-config">
306 MathJax.Hub.Config({
307 jax: ["input/TeX","output/HTML-CSS", "output/PreviewHTML"],
308 extensions: ["tex2jax.js","MathMenu.js","MathZoom.js", "fast-preview.js", "AssistiveMML.js", "[Contrib]/a11y/accessibility-menu.js"],
309 TeX: {
310 extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js","noUndefined.js"]
311 },
312 tex2jax: {
313 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
314 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
315 processEscapes: true,
316 processEnvironments: true
317 },
318 // Center justify equations in code and markdown cells. Elsewhere
319 // we use CSS to left justify single line equations in code cells.
320 displayAlign: 'center',
321 "HTML-CSS": {
322 styles: {'.MathJax_Display': {"margin": 0}},
323 linebreaks: { automatic: true }
324 },
325 showMathMenu: false
326 });
327 </script>
328 <!-- End of mathjax configuration -->
329 <script src="${h.asset('js/src/math_jax/MathJax.js')}"></script>
330 ''').render(h=helpers)
331
332 css = '<style>{}</style>'.format(
333 ''.join(_sanitize_resources(resources['inlining']['css'])))
334
335 body = '\n'.join([header, css, js, body])
336 return body, resources
337
338 notebook = nbformat.reads(source, as_version=4)
339 (body, resources) = as_html(notebook)
340 return body
341
266
342
267 class RstTemplateRenderer(object):
343 class RstTemplateRenderer(object):
268
344
General Comments 0
You need to be logged in to leave comments. Login now