Skip to content

Commit 31cb60e

Browse files
committed
unify markdown generation
1 parent 796f683 commit 31cb60e

File tree

10 files changed

+163
-119
lines changed

10 files changed

+163
-119
lines changed

notebook/static/base/js/markdown.js

Lines changed: 98 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 3 additions & 43 deletions
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

Lines changed: 8 additions & 19 deletions
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
/**
@@ -722,25 +721,15 @@ define([
722721
};
723722

724723

725-
var append_markdown = function(markdown, md, element) {
724+
var append_markdown = function(text, md, element) {
726725
var type = MIME_MARKDOWN;
727726
var toinsert = this.create_output_subarea(md, "output_markdown rendered_html", type);
728-
var text_and_math = mathjaxutils.remove_math(markdown);
729-
var text = text_and_math[0];
730-
var math = text_and_math[1];
731-
// Prevent marked from returning inline styles for table cells
732-
var renderer = new marked.Renderer();
733-
renderer.tablecell = function (content, flags) {
734-
var type = flags.header ? 'th' : 'td';
735-
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
736-
var start_tag = '<' + type + style + '>';
737-
var end_tag = '</' + type + '>\n';
738-
return start_tag + content + end_tag;
739-
};
740-
marked(text, { renderer: renderer }, function (err, html) {
741-
html = mathjaxutils.replace_math(html, math);
727+
markdown.render(text, {
728+
with_math: true,
729+
clean_tables: true
730+
}, function (err, html) {
742731
toinsert.append(html);
743-
});
732+
})
744733
dblclick_to_reset_size(toinsert.find('img'));
745734
element.append(toinsert);
746735
return toinsert;

notebook/static/notebook/js/textcell.js

Lines changed: 10 additions & 24 deletions
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'
@@ -19,11 +17,9 @@ define([
1917
utils,
2018
i18n,
2119
cell,
22-
security,
20+
markdown,
2321
configmod,
24-
mathjaxutils,
2522
celltoolbar,
26-
marked,
2723
CodeMirror,
2824
gfm,
2925
ipgfm
@@ -65,7 +61,6 @@ define([
6561
events: this.events}]);
6662

6763
this.cell_type = this.cell_type || 'text';
68-
mathjaxutils = mathjaxutils;
6964
this.rendered = false;
7065
};
7166

@@ -247,8 +242,9 @@ define([
247242
// can reference an image in markdown (using []() or a
248243
// HTML <img>)
249244
var text = this.get_text();
250-
marked(text, function (err, html) {
251-
html = $(security.sanitize_html_and_parse(html));
245+
markdown.render(text, {
246+
sanitize: true,
247+
}, function (err, html) {
252248
html.find('img[src^="attachment:"]').each(function (i, h) {
253249
h = $(h);
254250
var key = h.attr('src').replace(/^attachment:/, '');
@@ -388,21 +384,11 @@ define([
388384
var text = this.get_text();
389385
var math = null;
390386
if (text === "") { text = this.placeholder; }
391-
var text_and_math = mathjaxutils.remove_math(text);
392-
text = text_and_math[0];
393-
math = text_and_math[1];
394-
// Prevent marked from returning inline styles for table cells
395-
var renderer = new marked.Renderer();
396-
renderer.tablecell = function (content, flags) {
397-
var type = flags.header ? 'th' : 'td';
398-
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
399-
var start_tag = '<' + type + style + '>';
400-
var end_tag = '</' + type + '>\n';
401-
return start_tag + content + end_tag;
402-
};
403-
marked(text, { renderer: renderer }, function (err, html) {
404-
html = mathjaxutils.replace_math(html, math);
405-
html = $(security.sanitize_html_and_parse(html));
387+
markdown.render(text, {
388+
with_math: true,
389+
clean_tables: true,
390+
sanitize: true,
391+
}, function (err, html) {
406392
// add anchors to headings
407393
html.find(":header").addBack(":header").each(function (i, h) {
408394
h = $(h);

notebook/static/tree/js/directoryreadme.js

Lines changed: 15 additions & 24 deletions
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)