Notebook.js parses raw Jupyter/IPython notebooks, and lets you render them as HTML. See a working demo here.
Notebook.js works in the browser and in Node.js. Usage is fairly straightforward.
First, provide access to nb
via a script tag:
<script src="notebook.js"></script>
Then parse, render, and (perhaps) append:
var notebook = nb.parse(JSON.parse(raw_ipynb_json_string));
var rendered = notebook.render();
document.body.appendChild(rendered);
To install:
npm install notebookjs
Then parse, render, and write:
var fs = require ("fs");
var nb = require("notebookjs");
var ipynb = JSON.parse(fs.readFileSync("path/to/notebook.ipynb"));
var notebook = nb.parse(ipynb);
console.log(notebook.render().outerHTML);
On Node.js, notebook.js uses marked for Markdown rendering, and ansi_up for ANSI-coloring.
The browser-based version does not, however, ship with those libraries, so you must <script>
-include or require
them before initializing notebook.js.
To support other Markdown or ANSI-coloring engines, set nb.markdown
and/or nb.ansi
to functions that accept raw text and return rendered text.
On Node.js, notebook.js runs all "text/html"
-type outputs through DOMPurify. The browser-based version, however, does not ship with this library; to enable the default behavior, you must <script>
-include or require
it before initializing notebook.js.
Alternative sanitizers can be passed by setting nb.sanitizer
to a function that accepts a raw HTML string and returns a sanitized version. (To disable sanitization, set nb.sanitizer = function (x) { return x; };
.)
Notebook.js plays well with code-highlighting libraries. See NBPreview for an example of how to add support for your preferred highlighter. However, if you wish to inject your own highlighting, you can install a custom highlighter function by adding it under the highlighter
name in an notebookjs
instance. For instance, here is an implementation which colorizes languages using Prismjs during page generation for a static site:
var Prism = require('prismjs');
var highlighter = function(code, lang) {
if (typeof lang === 'undefined') lang = 'markup';
if (!Prism.languages.hasOwnProperty(lang)) {
try {
require('prismjs/components/prism-' + lang + '.js');
} catch (e) {
console.warn('** failed to load Prism lang: ' + lang);
Prism.languages[lang] = false;
}
}
return Prism.languages[lang] ? Prism.highlight(code, Prism.languages[lang]) : code;
};
var nb = require("notebookjs");
nb.highlighter = function(text, pre, code, lang) {
var language = lang || 'text';
pre.className = 'language-' + language;
if (typeof code != 'undefined') {
code.className = 'language-' + language;
}
return highlighter(text, language);
};
A highlighter
function takes up to four arguments:
text
-- text of the cell to highlightpre
-- the DOM<pre>
node that holds the cellcode
-- the DOM<code>
node that holds the cell (ifundefined
then text is not code)lang
-- the language of the code in the cell (ifundefined
then text is not code)
The function should at least return the original text
value if it cannot perform any highlighting.
Notebook.js currently doesn't support all of MathJax's syntaxes (MathML, AsciiMath, LaTeX). In the browser, however, it does support a significant subset of LaTeX via KaTeX. To enable this functionality, the webpage must have the following JavaScript and CSS libraries (or their equivalents, from other sources) loaded:
https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.js
https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/katex.min.css
https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.12.0/contrib/auto-render.min.js
The HTML rendered by notebook.js (intentionally) does not contain any styling. But each key element has fairly straightfoward CSS classes that make styling your notebooks a cinch. See nbpreview
's stylesheet for an example implementation.
Many thanks to the following users for catching bugs, fixing typos, and proposing useful features: