Skip to content

Commit cba4975

Browse files
committed
unify markdown generation
1 parent 8ef36d1 commit cba4975

File tree

10 files changed

+163
-119
lines changed

10 files changed

+163
-119
lines changed

notebook/static/base/js/markdown.js

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) Jupyter Development Team.
2+
// Distributed under the terms of the Modified BSD License.
3+
4+
define([
5+
'jquery',
6+
'base/js/utils',
7+
'base/js/mathjaxutils',
8+
'base/js/security',
9+
'components/marked/lib/marked',
10+
'codemirror/lib/codemirror',
11+
], function($, utils, mathjaxutils, security, marked, CodeMirror){
12+
"use strict";
13+
14+
marked.setOptions({
15+
gfm : true,
16+
tables: true,
17+
langPrefix: "cm-s-ipython language-",
18+
highlight: function(code, lang, callback) {
19+
if (!lang) {
20+
// no language, no highlight
21+
if (callback) {
22+
callback(null, code);
23+
return;
24+
} else {
25+
return code;
26+
}
27+
}
28+
utils.requireCodeMirrorMode(lang, function (spec) {
29+
var el = document.createElement("div");
30+
var mode = CodeMirror.getMode({}, spec);
31+
if (!mode) {
32+
console.log("No CodeMirror mode: " + lang);
33+
callback(null, code);
34+
return;
35+
}
36+
try {
37+
CodeMirror.runMode(code, spec, el);
38+
callback(null, el.innerHTML);
39+
} catch (err) {
40+
console.log("Failed to highlight " + lang + " code", err);
41+
callback(err, code);
42+
}
43+
}, function (err) {
44+
console.log("No CodeMirror mode: " + lang);
45+
console.log("Require CodeMirror mode error: " + err);
46+
callback(null, code);
47+
});
48+
}
49+
});
50+
51+
var mathjax_init_done = false;
52+
function ensure_mathjax_init() {
53+
if(!mathjax_init_done) {
54+
mathjax_init_done = true;
55+
mathjaxutils.init();
56+
}
57+
}
58+
59+
function render(markdown, options, callback) {
60+
options = $.extend({
61+
// Apply mathjax transformation
62+
with_math: false,
63+
// Prevent marked from returning inline styles for table cells
64+
clean_tables: false
65+
}, options);
66+
var renderer = new marked.Renderer();
67+
if(options.clean_tables) {
68+
renderer.tablecell = function (content, flags) {
69+
var type = flags.header ? 'th' : 'td';
70+
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
71+
var start_tag = '<' + type + style + '>';
72+
var end_tag = '</' + type + '>\n';
73+
return start_tag + content + end_tag;
74+
};
75+
}
76+
var text = markdown;
77+
var math = null;
78+
if(options.with_math) {
79+
ensure_mathjax_init();
80+
var text_and_math = mathjaxutils.remove_math(markdown);
81+
text = text_and_math[0];
82+
math = text_and_math[1];
83+
}
84+
marked(text, { renderer: renderer }, function (err, html) {
85+
if(!err) {
86+
if(options.with_math) {
87+
html = mathjaxutils.replace_math(html, math);
88+
}
89+
if(options.sanitize) {
90+
html = $(security.sanitize_html_and_parse(html));
91+
}
92+
}
93+
callback(err, html);
94+
});
95+
}
96+
97+
return {'render': render};
98+
});

notebook/static/base/js/namespace.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ define(function(){
3232
// expose modules
3333

3434
jprop('utils','base/js/utils')
35+
jprop('mathjaxutils','base/js/mathjaxutils');
3536

3637
//Jupyter.load_extensions = Jupyter.utils.load_extensions;
3738
//
3839
jprop('security','base/js/security');
3940
jprop('keyboard','base/js/keyboard');
4041
jprop('dialog','base/js/dialog');
41-
jprop('mathjaxutils','notebook/js/mathjaxutils');
4242

4343

4444
//// exposed constructors

notebook/static/notebook/js/notebook.js

+3-43
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@ define([
1212
'base/js/utils',
1313
'base/js/i18n',
1414
'base/js/dialog',
15+
'base/js/markdown',
1516
'./cell',
1617
'./textcell',
1718
'./codecell',
1819
'moment',
1920
'services/config',
2021
'services/sessions/session',
2122
'./celltoolbar',
22-
'components/marked/lib/marked',
2323
'codemirror/lib/codemirror',
2424
'codemirror/addon/runmode/runmode',
25-
'./mathjaxutils',
25+
'base/js/mathjaxutils',
2626
'base/js/keyboard',
2727
'./tooltip',
2828
'./celltoolbarpresets/default',
@@ -40,14 +40,14 @@ define([
4040
utils,
4141
i18n,
4242
dialog,
43+
markdown,
4344
cellmod,
4445
textcell,
4546
codecell,
4647
moment,
4748
configmod,
4849
session,
4950
celltoolbar,
50-
marked,
5151
CodeMirror,
5252
runMode,
5353
mathjaxutils,
@@ -116,46 +116,6 @@ define([
116116

117117
mathjaxutils.init();
118118

119-
if (marked) {
120-
marked.setOptions({
121-
gfm : true,
122-
tables: true,
123-
// FIXME: probably want central config for CodeMirror theme when we have js config
124-
langPrefix: "cm-s-ipython language-",
125-
highlight: function(code, lang, callback) {
126-
if (!lang) {
127-
// no language, no highlight
128-
if (callback) {
129-
callback(null, code);
130-
return;
131-
} else {
132-
return code;
133-
}
134-
}
135-
utils.requireCodeMirrorMode(lang, function (spec) {
136-
var el = document.createElement("div");
137-
var mode = CodeMirror.getMode({}, spec);
138-
if (!mode) {
139-
console.log("No CodeMirror mode: " + lang);
140-
callback(null, code);
141-
return;
142-
}
143-
try {
144-
CodeMirror.runMode(code, spec, el);
145-
callback(null, el.innerHTML);
146-
} catch (err) {
147-
console.log("Failed to highlight " + lang + " code", err);
148-
callback(err, code);
149-
}
150-
}, function (err) {
151-
console.log("No CodeMirror mode: " + lang);
152-
console.log("Require CodeMirror mode error: " + err);
153-
callback(null, code);
154-
});
155-
}
156-
});
157-
}
158-
159119
this.element = $(selector);
160120
this.element.scroll();
161121
this.element.data("notebook", this);

notebook/static/notebook/js/outputarea.js

+8-19
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ define([
77
'base/js/i18n',
88
'base/js/security',
99
'base/js/keyboard',
10+
'base/js/markdown',
1011
'services/config',
11-
'notebook/js/mathjaxutils',
12-
'components/marked/lib/marked',
13-
], function($, utils, i18n, security, keyboard, configmod, mathjaxutils, marked) {
12+
], function($, utils, i18n, security, keyboard, markdown, configmod) {
1413
"use strict";
1514

1615
/**
@@ -728,25 +727,15 @@ define([
728727
};
729728

730729

731-
var append_markdown = function(markdown, md, element) {
730+
var append_markdown = function(text, md, element) {
732731
var type = MIME_MARKDOWN;
733732
var toinsert = this.create_output_subarea(md, "output_markdown rendered_html", type);
734-
var text_and_math = mathjaxutils.remove_math(markdown);
735-
var text = text_and_math[0];
736-
var math = text_and_math[1];
737-
// Prevent marked from returning inline styles for table cells
738-
var renderer = new marked.Renderer();
739-
renderer.tablecell = function (content, flags) {
740-
var type = flags.header ? 'th' : 'td';
741-
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
742-
var start_tag = '<' + type + style + '>';
743-
var end_tag = '</' + type + '>\n';
744-
return start_tag + content + end_tag;
745-
};
746-
marked(text, { renderer: renderer }, function (err, html) {
747-
html = mathjaxutils.replace_math(html, math);
733+
markdown.render(text, {
734+
with_math: true,
735+
clean_tables: true
736+
}, function (err, html) {
748737
toinsert.append(html);
749-
});
738+
})
750739
dblclick_to_reset_size(toinsert.find('img'));
751740
element.append(toinsert);
752741
return toinsert;

notebook/static/notebook/js/textcell.js

+10-24
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@ define([
66
'base/js/utils',
77
'base/js/i18n',
88
'notebook/js/cell',
9-
'base/js/security',
9+
'base/js/markdown',
1010
'services/config',
11-
'notebook/js/mathjaxutils',
1211
'notebook/js/celltoolbar',
13-
'components/marked/lib/marked',
1412
'codemirror/lib/codemirror',
1513
'codemirror/mode/gfm/gfm',
1614
'notebook/js/codemirror-ipythongfm',
@@ -20,11 +18,9 @@ define([
2018
utils,
2119
i18n,
2220
cell,
23-
security,
21+
markdown,
2422
configmod,
25-
mathjaxutils,
2623
celltoolbar,
27-
marked,
2824
CodeMirror,
2925
gfm,
3026
ipgfm,
@@ -67,7 +63,6 @@ define([
6763
events: this.events}]);
6864

6965
this.cell_type = this.cell_type || 'text';
70-
mathjaxutils = mathjaxutils;
7166
this.rendered = false;
7267
};
7368

@@ -249,8 +244,9 @@ define([
249244
// can reference an image in markdown (using []() or a
250245
// HTML <img>)
251246
var text = this.get_text();
252-
marked(text, function (err, html) {
253-
html = $(security.sanitize_html_and_parse(html));
247+
markdown.render(text, {
248+
sanitize: true,
249+
}, function (err, html) {
254250
html.find('img[src^="attachment:"]').each(function (i, h) {
255251
h = $(h);
256252
var key = h.attr('src').replace(/^attachment:/, '');
@@ -391,21 +387,11 @@ define([
391387
var text = this.get_text();
392388
var math = null;
393389
if (text === "") { text = this.placeholder; }
394-
var text_and_math = mathjaxutils.remove_math(text);
395-
text = text_and_math[0];
396-
math = text_and_math[1];
397-
// Prevent marked from returning inline styles for table cells
398-
var renderer = new marked.Renderer();
399-
renderer.tablecell = function (content, flags) {
400-
var type = flags.header ? 'th' : 'td';
401-
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
402-
var start_tag = '<' + type + style + '>';
403-
var end_tag = '</' + type + '>\n';
404-
return start_tag + content + end_tag;
405-
};
406-
marked(text, { renderer: renderer }, function (err, html) {
407-
html = mathjaxutils.replace_math(html, math);
408-
html = $(security.sanitize_html_and_parse(html));
390+
markdown.render(text, {
391+
with_math: true,
392+
clean_tables: true,
393+
sanitize: true,
394+
}, function (err, html) {
409395
// add anchors to headings
410396
html.find(":header").addBack(":header").each(function (i, h) {
411397
h = $(h);

notebook/static/tree/js/directoryreadme.js

+15-24
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ define([
55
'jquery',
66
'base/js/utils',
77
'base/js/events',
8-
'components/marked/lib/marked'
9-
], function ($, utils, events, marked) {
8+
'base/js/markdown',
9+
'base/js/mathjaxutils',
10+
], function ($, utils, events, markdown, mathjaxutils) {
1011
"use strict";
1112

1213
var DirectoryReadme = function (selector, notebook_list, options) {
@@ -73,32 +74,17 @@ define([
7374

7475
this.title = $("<a />");
7576
$("<div/>")
76-
.addClass("list_header row")
77+
.addClass("list_header row readme_header")
7778
.html([
7879
$('<i/>')
7980
.addClass('item_icon file_icon'),
8081
this.title
8182
]).appendTo(element);
8283

8384

84-
var frame = $("<iframe/>")
85-
.attr("src", "about:blank")
86-
.attr("sandbox", "allow-same-origin")
85+
this.page = $("<div/>")
86+
.addClass("readme_content")
8787
.appendTo(element);
88-
89-
frame.on("load", function() {
90-
var contents = frame.contents();
91-
contents.find("head")
92-
.append($("<link/>")
93-
.attr("rel", "stylesheet")
94-
.attr("type","text/css")
95-
.attr("href", utils.url_path_join(
96-
element.data("static-url"),
97-
"style",
98-
"style.min.css"
99-
)));
100-
});
101-
this.frame = frame;
10288
}
10389

10490
DirectoryReadme.prototype.clear_readme = function () {
@@ -117,10 +103,15 @@ define([
117103
utils.encode_uri_components(file.path)
118104
))
119105
.text(file.name);
120-
this.frame.height(0); // reset height
121-
var contents = this.frame.contents();
122-
contents.find("body").html(marked(file.content));
123-
this.frame.height(contents.height());
106+
107+
var page = this.page;
108+
markdown.render(file.content, {
109+
with_math: true,
110+
sanitize: true
111+
}, function(err, html) {
112+
page.html(html);
113+
utils.typeset(page);
114+
});
124115
};
125116

126117
return {'DirectoryReadme': DirectoryReadme};

0 commit comments

Comments
 (0)