##// 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 38 import hashlib
39 39 import pygments
40 40 import itertools
41 import fnmatch
41 42
42 43 from datetime import datetime
43 44 from functools import partial
@@ -1811,27 +1812,15 b' def urlify_commit_message(commit_text, r'
1811 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 1815 def renderer_from_filename(filename, exclude=None):
1826 1816 """
1827 1817 choose a renderer based on filename
1828 1818 """
1829 1819
1830 # images
1831
1832 1820 # ipython
1833 if filename.endswith('.ipynb'):
1834 return 'ipython'
1821 for ext in ['*.ipynb']:
1822 if fnmatch.fnmatch(filename, pat=ext):
1823 return 'jupyter'
1835 1824
1836 1825 is_markup = MarkupRenderer.renderer_from_filename(filename, exclude=exclude)
1837 1826 if is_markup:
@@ -1841,26 +1830,18 b' def renderer_from_filename(filename, exc'
1841 1830
1842 1831 def render(source, renderer='rst', mentions=False):
1843 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 1836 elif renderer == 'markdown':
1846 return markdown(source, mentions=mentions)
1847 elif renderer == 'ipython':
1848 def ipython_renderer(source):
1849 import nbformat
1850 from nbconvert import HTMLExporter
1851 notebook = nbformat.reads(source, as_version=4)
1837 return literal(
1838 '<div class="markdown-block">%s</div>' %
1839 MarkupRenderer.markdown(source, flavored=True, mentions=mentions))
1840 elif renderer == 'jupyter':
1841 return literal(
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 1845 # None means just show the file-source
1865 1846 return None
1866 1847
@@ -29,6 +29,7 b' import logging'
29 29 import itertools
30 30
31 31 from mako.lookup import TemplateLookup
32 from mako.template import Template as MakoTemplate
32 33
33 34 from docutils.core import publish_parts
34 35 from docutils.parsers.rst import directives
@@ -49,6 +50,7 b' class MarkupRenderer(object):'
49 50
50 51 MARKDOWN_PAT = re.compile(r'\.(md|mkdn?|mdown|markdown)$', re.IGNORECASE)
51 52 RST_PAT = re.compile(r'\.re?st$', re.IGNORECASE)
53 JUPYTER_PAT = re.compile(r'\.(ipynb)$', re.IGNORECASE)
52 54 PLAIN_PAT = re.compile(r'^readme$', re.IGNORECASE)
53 55
54 56 extensions = ['codehilite', 'extra', 'def_list', 'sane_lists']
@@ -95,6 +97,8 b' class MarkupRenderer(object):'
95 97 detected_renderer = 'markdown'
96 98 elif MarkupRenderer.RST_PAT.findall(filename):
97 99 detected_renderer = 'rst'
100 elif MarkupRenderer.JUPYTER_PAT.findall(filename):
101 detected_renderer = 'jupyter'
98 102 elif MarkupRenderer.PLAIN_PAT.findall(filename):
99 103 detected_renderer = 'plain'
100 104 else:
@@ -263,6 +267,78 b' class MarkupRenderer(object):'
263 267 else:
264 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 343 class RstTemplateRenderer(object):
268 344
General Comments 0
You need to be logged in to leave comments. Login now