diff --git a/previewer_jupyter/README.md b/previewer_jupyter/README.md index ffec4aa..b1d6949 100644 --- a/previewer_jupyter/README.md +++ b/previewer_jupyter/README.md @@ -5,6 +5,10 @@ material to an Indico event. ## Changelog +### 3.2 + +- Replace MathJax with Katex for auto math rendering + ### 3.0 - Initial release for Indico 3.0 diff --git a/previewer_jupyter/indico_previewer_jupyter/client/index.css b/previewer_jupyter/indico_previewer_jupyter/client/index.css new file mode 100644 index 0000000..4811e38 --- /dev/null +++ b/previewer_jupyter/indico_previewer_jupyter/client/index.css @@ -0,0 +1,9 @@ +/* This file is part of the Indico plugins. + * Copyright (C) 2002 - 2022 CERN + * + * The Indico plugins are free software; you can redistribute + * them and/or modify them under the terms of the MIT License; + * see the LICENSE file for more details. + */ + +@import '~katex/dist/katex.css'; diff --git a/previewer_jupyter/indico_previewer_jupyter/client/index.js b/previewer_jupyter/indico_previewer_jupyter/client/index.js new file mode 100644 index 0000000..24258f0 --- /dev/null +++ b/previewer_jupyter/indico_previewer_jupyter/client/index.js @@ -0,0 +1,26 @@ +// This file is part of the Indico plugins. +// Copyright (C) 2002 - 2022 CERN +// +// The Indico plugins are free software; you can redistribute +// them and/or modify them under the terms of the MIT License; +// see the LICENSE file for more details. + +import renderMathInElement from 'katex/dist/contrib/auto-render.js'; +import './index.css'; + +document.addEventListener('DOMContentLoaded', function() { + const element = document.getElementById('notebook-wrapper'); + renderMathInElement(element, { + delimiters: [ + {left: '$$', right: '$$', display: true}, + {left: '$', right: '$', display: false}, + {left: '\\(', right: '\\)', display: false}, + {left: '\\begin{equation}', right: '\\end{equation}', display: true}, + {left: '\\begin{align}', right: '\\end{align}', display: true}, + {left: '\\begin{alignat}', right: '\\end{alignat}', display: true}, + {left: '\\begin{gather}', right: '\\end{gather}', display: true}, + {left: '\\begin{CD}', right: '\\end{CD}', display: true}, + {left: '\\[', right: '\\]', display: true}, + ], + }); +}); diff --git a/previewer_jupyter/indico_previewer_jupyter/controllers.py b/previewer_jupyter/indico_previewer_jupyter/controllers.py index 5b15894..ae9cbba 100644 --- a/previewer_jupyter/indico_previewer_jupyter/controllers.py +++ b/previewer_jupyter/indico_previewer_jupyter/controllers.py @@ -5,10 +5,9 @@ # them and/or modify them under the terms of the MIT License; # see the LICENSE file for more details. -from uuid import uuid4 - import nbformat from flask import current_app, render_template, request, session +from flask_pluginengine import current_plugin from nbconvert.exporters import HTMLExporter from traitlets.config import Config from werkzeug.exceptions import Forbidden @@ -30,7 +29,11 @@ class RHEventPreviewIPyNB(RH): def _process(self): config = Config() config.HTMLExporter.preprocessors = [CppHighlighter] - config.HTMLExporter.template_file = 'basic' + config.HTMLExporter.template_name = 'classic' + # Disable unused extensions + config.HTMLExporter.mathjax_url = '' + config.HTMLExporter.jquery_url = '' + config.HTMLExporter.require_js_url = '' with self.attachment.file.open() as f: notebook = nbformat.read(f, as_version=4) @@ -39,13 +42,12 @@ class RHEventPreviewIPyNB(RH): body, resources = html_exporter.from_notebook_node(notebook) css_code = '\n'.join(resources['inlining'].get('css', [])) - nonce = str(uuid4()) html = render_template('previewer_jupyter:ipynb_preview.html', attachment=self.attachment, - html_code=body, css_code=css_code, nonce=nonce) + html_code=body, css_code=css_code, plugin=current_plugin) response = current_app.response_class(html) # Use CSP to restrict access to possibly malicious scripts or inline JS - csp_header = f"script-src cdn.mathjax.org 'nonce-{nonce}';" + csp_header = "script-src 'self';" response.headers['Content-Security-Policy'] = csp_header response.headers['X-Webkit-CSP'] = csp_header # IE10 doesn't have proper CSP support, so we need to be more strict diff --git a/previewer_jupyter/indico_previewer_jupyter/templates/ipynb_preview.html b/previewer_jupyter/indico_previewer_jupyter/templates/ipynb_preview.html index 1a2228e..893afb1 100644 --- a/previewer_jupyter/indico_previewer_jupyter/templates/ipynb_preview.html +++ b/previewer_jupyter/indico_previewer_jupyter/templates/ipynb_preview.html @@ -5,27 +5,12 @@ + {{ plugin.manifest['main.css'] }} + {{ plugin.manifest['main.js'] }} - {{ html_code | safe }} - - +
+ {{ html_code | safe }} +
diff --git a/previewer_jupyter/package.json b/previewer_jupyter/package.json new file mode 100644 index 0000000..87fca9b --- /dev/null +++ b/previewer_jupyter/package.json @@ -0,0 +1,7 @@ +{ + "private": true, + "name": "indico-plugin-previewer-jupyter", + "dependencies": { + "katex": "^0.15.3" + } +} diff --git a/previewer_jupyter/setup.cfg b/previewer_jupyter/setup.cfg index 0023e58..91152f1 100644 --- a/previewer_jupyter/setup.cfg +++ b/previewer_jupyter/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = indico-plugin-previewer-jupyter -version = 3.0 +version = 3.2-dev description = Jupyter notebook rendering for attachments in Indico long_description = file: README.md long_description_content_type = text/markdown; charset=UTF-8; variant=GFM @@ -20,8 +20,8 @@ zip_safe = false include_package_data = true python_requires = ~=3.9.0 install_requires = - indico>=3.0 - nbconvert==5.6.1 + indico>=3.2.dev0 + nbconvert==6.5.0 [options.entry_points] indico.plugins = diff --git a/previewer_jupyter/webpack-bundles.json b/previewer_jupyter/webpack-bundles.json new file mode 100644 index 0000000..5f28835 --- /dev/null +++ b/previewer_jupyter/webpack-bundles.json @@ -0,0 +1,5 @@ +{ + "entry": { + "main": "./index.js" + } +}