Skip to content

Commit e620b12

Browse files
authored
Merge pull request #1155 from jcb91/livemdpreview
[livemdpreview] add new nbextension!
2 parents 9553817 + c76e689 commit e620b12

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
define([
2+
'jquery',
3+
'require',
4+
'base/js/namespace',
5+
'base/js/events',
6+
'base/js/utils',
7+
'notebook/js/cell',
8+
'notebook/js/textcell',
9+
'codemirror/lib/codemirror',
10+
], function (
11+
$,
12+
require,
13+
Jupyter,
14+
events,
15+
utils,
16+
cell_mod,
17+
textcell,
18+
CodeMirror
19+
) {
20+
"use strict";
21+
22+
var LiveMdPreviewer = function(options) {
23+
options = $.extend(true, {}, this._default_options, options);
24+
this.show_side_by_side = options.show_side_by_side;
25+
this.timeout = Math.max(50, options.timeout);
26+
27+
this.addCSS();
28+
var lmdp = this;
29+
// Change any existing cells:
30+
Jupyter.notebook.get_cells().forEach(function (cell) {
31+
lmdp.registerCell(cell);
32+
});
33+
// Ensure we also apply to new cells:
34+
events.on('create.Cell', function (evt, data) { lmdp.registerCell(data.cell); });
35+
};
36+
37+
LiveMdPreviewer.prototype._default_options = {
38+
show_side_by_side: false,
39+
timeout : 500,
40+
};
41+
42+
/**
43+
* do work of rendering the markdown cell, without triggering the rendered
44+
* event, or altering classes on elements
45+
*/
46+
var previewMdCell = function(cell) {
47+
var cached_trigger = cell.events.trigger;
48+
cell.events.trigger = function (eventType) {
49+
if (eventType !== "rendered.MarkdownCell") {
50+
return cached_trigger.apply(this, arguments);
51+
}
52+
return this;
53+
};
54+
55+
var Cell = cell_mod.Cell;
56+
var cached_render = Cell.prototype.render;
57+
Cell.prototype.render = function () {
58+
return true;
59+
};
60+
61+
try {
62+
cell.render();
63+
}
64+
finally {
65+
cell.events.trigger = cached_trigger;
66+
Cell.prototype.render = cached_render;
67+
}
68+
};
69+
70+
LiveMdPreviewer.prototype.registerCell = function(cell) {
71+
if (!(cell instanceof textcell.TextCell)) {
72+
return;
73+
}
74+
var timeout = this.timeout;
75+
cell.code_mirror.on('changes', function onCodeMirrorChanges (cm, changes) {
76+
if (!cm.state.livemdpreview) {
77+
cm.state.livemdpreview = setTimeout(function () {
78+
var cell = $(cm.getWrapperElement()).closest('.cell').data('cell');
79+
previewMdCell(cell);
80+
delete cm.state.livemdpreview;
81+
}, timeout);
82+
}
83+
});
84+
};
85+
86+
LiveMdPreviewer.prototype.addCSS = function () {
87+
var styles_elem = $('#livemdpreviewstyles');
88+
if (styles_elem.length < 1) {
89+
styles_elem = $('<style id="livemdpreviewstyles">').appendTo('body');
90+
}
91+
var styles = [
92+
// show rendered stuff even in "unrendered" cell
93+
'.text_cell.unrendered .text_cell_render { display: block; }',
94+
];
95+
if (this.show_side_by_side) {
96+
styles.push('.text_cell.unrendered .inner_cell { flex-direction: row !important; }');
97+
styles.push('.text_cell.unrendered .input_area, .text_cell.unrendered .text_cell_render { width: 50%; }');
98+
}
99+
styles_elem.html(styles.join('\n'));
100+
};
101+
102+
/**
103+
* Export things
104+
*/
105+
return {
106+
load_ipython_extension : function () {
107+
return Jupyter.notebook.config.loaded.then(function () {
108+
return new LiveMdPreviewer(Jupyter.notebook.config.data.livemdpreview);
109+
});
110+
}
111+
};
112+
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Type: Jupyter Notebook Extension
2+
Compatibility: 4.x, 5.x
3+
Name: Live Markdown Preview
4+
Main: livemdpreview.js
5+
Description: |
6+
Live-preview the rendered output of markdown cells while editing their source.
7+
Parameters:
8+
9+
- name: livemdpreview.show_side_by_side
10+
description: |
11+
Show the input & output of markdown cells side-by-side while editing them.
12+
Otherwise, the output appears immediately below the input while editing
13+
input_type: checkbox
14+
default: false
15+
16+
- name: livemdpreview.timeout
17+
description: |
18+
Minimum time in ms between editing the markdown source & its output being
19+
updated. This throttles the rate at which consecutive renderings will take
20+
place.
21+
input_type: number
22+
default: 500
23+
min: 10
24+
step: 10

0 commit comments

Comments
 (0)