unify markdown generation

Toon Baeyens 6 years ago
parent 8ef36d1868
commit cba497548c

@ -0,0 +1,98 @@
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
define([
'jquery',
'base/js/utils',
'base/js/mathjaxutils',
'base/js/security',
'components/marked/lib/marked',
'codemirror/lib/codemirror',
], function($, utils, mathjaxutils, security, marked, CodeMirror){
"use strict";
marked.setOptions({
gfm : true,
tables: true,
langPrefix: "cm-s-ipython language-",
highlight: function(code, lang, callback) {
if (!lang) {
// no language, no highlight
if (callback) {
callback(null, code);
return;
} else {
return code;
}
}
utils.requireCodeMirrorMode(lang, function (spec) {
var el = document.createElement("div");
var mode = CodeMirror.getMode({}, spec);
if (!mode) {
console.log("No CodeMirror mode: " + lang);
callback(null, code);
return;
}
try {
CodeMirror.runMode(code, spec, el);
callback(null, el.innerHTML);
} catch (err) {
console.log("Failed to highlight " + lang + " code", err);
callback(err, code);
}
}, function (err) {
console.log("No CodeMirror mode: " + lang);
console.log("Require CodeMirror mode error: " + err);
callback(null, code);
});
}
});
var mathjax_init_done = false;
function ensure_mathjax_init() {
if(!mathjax_init_done) {
mathjax_init_done = true;
mathjaxutils.init();
}
}
function render(markdown, options, callback) {
options = $.extend({
// Apply mathjax transformation
with_math: false,
// Prevent marked from returning inline styles for table cells
clean_tables: false
}, options);
var renderer = new marked.Renderer();
if(options.clean_tables) {
renderer.tablecell = function (content, flags) {
var type = flags.header ? 'th' : 'td';
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
var start_tag = '<' + type + style + '>';
var end_tag = '</' + type + '>\n';
return start_tag + content + end_tag;
};
}
var text = markdown;
var math = null;
if(options.with_math) {
ensure_mathjax_init();
var text_and_math = mathjaxutils.remove_math(markdown);
text = text_and_math[0];
math = text_and_math[1];
}
marked(text, { renderer: renderer }, function (err, html) {
if(!err) {
if(options.with_math) {
html = mathjaxutils.replace_math(html, math);
}
if(options.sanitize) {
html = $(security.sanitize_html_and_parse(html));
}
}
callback(err, html);
});
}
return {'render': render};
});

@ -32,13 +32,13 @@ define(function(){
// expose modules
jprop('utils','base/js/utils')
jprop('mathjaxutils','base/js/mathjaxutils');
//Jupyter.load_extensions = Jupyter.utils.load_extensions;
//
jprop('security','base/js/security');
jprop('keyboard','base/js/keyboard');
jprop('dialog','base/js/dialog');
jprop('mathjaxutils','notebook/js/mathjaxutils');
//// exposed constructors

@ -12,6 +12,7 @@ define([
'base/js/utils',
'base/js/i18n',
'base/js/dialog',
'base/js/markdown',
'./cell',
'./textcell',
'./codecell',
@ -19,10 +20,9 @@ define([
'services/config',
'services/sessions/session',
'./celltoolbar',
'components/marked/lib/marked',
'codemirror/lib/codemirror',
'codemirror/addon/runmode/runmode',
'./mathjaxutils',
'base/js/mathjaxutils',
'base/js/keyboard',
'./tooltip',
'./celltoolbarpresets/default',
@ -40,6 +40,7 @@ define([
utils,
i18n,
dialog,
markdown,
cellmod,
textcell,
codecell,
@ -47,7 +48,6 @@ define([
configmod,
session,
celltoolbar,
marked,
CodeMirror,
runMode,
mathjaxutils,
@ -116,46 +116,6 @@ define([
mathjaxutils.init();
if (marked) {
marked.setOptions({
gfm : true,
tables: true,
// FIXME: probably want central config for CodeMirror theme when we have js config
langPrefix: "cm-s-ipython language-",
highlight: function(code, lang, callback) {
if (!lang) {
// no language, no highlight
if (callback) {
callback(null, code);
return;
} else {
return code;
}
}
utils.requireCodeMirrorMode(lang, function (spec) {
var el = document.createElement("div");
var mode = CodeMirror.getMode({}, spec);
if (!mode) {
console.log("No CodeMirror mode: " + lang);
callback(null, code);
return;
}
try {
CodeMirror.runMode(code, spec, el);
callback(null, el.innerHTML);
} catch (err) {
console.log("Failed to highlight " + lang + " code", err);
callback(err, code);
}
}, function (err) {
console.log("No CodeMirror mode: " + lang);
console.log("Require CodeMirror mode error: " + err);
callback(null, code);
});
}
});
}
this.element = $(selector);
this.element.scroll();
this.element.data("notebook", this);

@ -7,10 +7,9 @@ define([
'base/js/i18n',
'base/js/security',
'base/js/keyboard',
'base/js/markdown',
'services/config',
'notebook/js/mathjaxutils',
'components/marked/lib/marked',
], function($, utils, i18n, security, keyboard, configmod, mathjaxutils, marked) {
], function($, utils, i18n, security, keyboard, markdown, configmod) {
"use strict";
/**
@ -728,25 +727,15 @@ define([
};
var append_markdown = function(markdown, md, element) {
var append_markdown = function(text, md, element) {
var type = MIME_MARKDOWN;
var toinsert = this.create_output_subarea(md, "output_markdown rendered_html", type);
var text_and_math = mathjaxutils.remove_math(markdown);
var text = text_and_math[0];
var math = text_and_math[1];
// Prevent marked from returning inline styles for table cells
var renderer = new marked.Renderer();
renderer.tablecell = function (content, flags) {
var type = flags.header ? 'th' : 'td';
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
var start_tag = '<' + type + style + '>';
var end_tag = '</' + type + '>\n';
return start_tag + content + end_tag;
};
marked(text, { renderer: renderer }, function (err, html) {
html = mathjaxutils.replace_math(html, math);
markdown.render(text, {
with_math: true,
clean_tables: true
}, function (err, html) {
toinsert.append(html);
});
})
dblclick_to_reset_size(toinsert.find('img'));
element.append(toinsert);
return toinsert;

@ -6,11 +6,9 @@ define([
'base/js/utils',
'base/js/i18n',
'notebook/js/cell',
'base/js/security',
'base/js/markdown',
'services/config',
'notebook/js/mathjaxutils',
'notebook/js/celltoolbar',
'components/marked/lib/marked',
'codemirror/lib/codemirror',
'codemirror/mode/gfm/gfm',
'notebook/js/codemirror-ipythongfm',
@ -20,11 +18,9 @@ define([
utils,
i18n,
cell,
security,
markdown,
configmod,
mathjaxutils,
celltoolbar,
marked,
CodeMirror,
gfm,
ipgfm,
@ -67,7 +63,6 @@ define([
events: this.events}]);
this.cell_type = this.cell_type || 'text';
mathjaxutils = mathjaxutils;
this.rendered = false;
};
@ -249,8 +244,9 @@ define([
// can reference an image in markdown (using []() or a
// HTML <img>)
var text = this.get_text();
marked(text, function (err, html) {
html = $(security.sanitize_html_and_parse(html));
markdown.render(text, {
sanitize: true,
}, function (err, html) {
html.find('img[src^="attachment:"]').each(function (i, h) {
h = $(h);
var key = h.attr('src').replace(/^attachment:/, '');
@ -391,21 +387,11 @@ define([
var text = this.get_text();
var math = null;
if (text === "") { text = this.placeholder; }
var text_and_math = mathjaxutils.remove_math(text);
text = text_and_math[0];
math = text_and_math[1];
// Prevent marked from returning inline styles for table cells
var renderer = new marked.Renderer();
renderer.tablecell = function (content, flags) {
var type = flags.header ? 'th' : 'td';
var style = flags.align == null ? '': ' style="text-align: ' + flags.align + '"';
var start_tag = '<' + type + style + '>';
var end_tag = '</' + type + '>\n';
return start_tag + content + end_tag;
};
marked(text, { renderer: renderer }, function (err, html) {
html = mathjaxutils.replace_math(html, math);
html = $(security.sanitize_html_and_parse(html));
markdown.render(text, {
with_math: true,
clean_tables: true,
sanitize: true,
}, function (err, html) {
// add anchors to headings
html.find(":header").addBack(":header").each(function (i, h) {
h = $(h);

@ -5,8 +5,9 @@ define([
'jquery',
'base/js/utils',
'base/js/events',
'components/marked/lib/marked'
], function ($, utils, events, marked) {
'base/js/markdown',
'base/js/mathjaxutils',
], function ($, utils, events, markdown, mathjaxutils) {
"use strict";
var DirectoryReadme = function (selector, notebook_list, options) {
@ -73,7 +74,7 @@ define([
this.title = $("<a />");
$("<div/>")
.addClass("list_header row")
.addClass("list_header row readme_header")
.html([
$('<i/>')
.addClass('item_icon file_icon'),
@ -81,24 +82,9 @@ define([
]).appendTo(element);
var frame = $("<iframe/>")
.attr("src", "about:blank")
.attr("sandbox", "allow-same-origin")
this.page = $("<div/>")
.addClass("readme_content")
.appendTo(element);
frame.on("load", function() {
var contents = frame.contents();
contents.find("head")
.append($("<link/>")
.attr("rel", "stylesheet")
.attr("type","text/css")
.attr("href", utils.url_path_join(
element.data("static-url"),
"style",
"style.min.css"
)));
});
this.frame = frame;
}
DirectoryReadme.prototype.clear_readme = function () {
@ -117,10 +103,15 @@ define([
utils.encode_uri_components(file.path)
))
.text(file.name);
this.frame.height(0); // reset height
var contents = this.frame.contents();
contents.find("body").html(marked(file.content));
this.frame.height(contents.height());
var page = this.page;
markdown.render(file.content, {
with_math: true,
sanitize: true
}, function(err, html) {
page.html(html);
utils.typeset(page);
});
};
return {'DirectoryReadme': DirectoryReadme};

@ -15,8 +15,11 @@
// The left padding of the selector button's contents.
@dashboard-selectorbtn-lpad: 7px;
// The horizontal padding of the readme iframe.
// The horizontal padding of the readme.
@dashboard_readme_lr_pad: 21px;
// The vertical padding of the readme.
@dashboard_readme_top_pad: 7px;
@dashboard_readme_bottom_pad: 14px;
ul#tabs {
margin-bottom: @dashboard_tb_pad;
@ -462,16 +465,14 @@ outline-width:1px;
}
#directory_readme {
&>div {
.readme_header {
padding-top: @dashboard_tb_pad;
padding-bottom: @dashboard_tb_pad;
padding-left: @dashboard_lr_pad;
padding-right: @dashboard_lr_pad;
}
iframe {
padding: @dashboard_tb_pad @dashboard_readme_lr_pad;
border: 0;
width: 100%;
.readme_content {
padding: @dashboard_readme_top_pad @dashboard_readme_lr_pad @dashboard_readme_bottom_pad;
}
}

@ -1,5 +1,22 @@
{% extends "page.html" %}
{% block stylesheet %}
{% if mathjax_url %}
<script type="text/javascript" src="{{mathjax_url}}?config={{mathjax_config}}&delayStartupUntil=configured" charset="utf-8"></script>
{% endif %}
<script type="text/javascript">
// MathJax disabled, set as null to distinguish from *missing* MathJax,
// where it will be undefined, and should prompt a dialog later.
window.mathjax_url = "{{mathjax_url}}";
</script>
<link rel="stylesheet" href="{{ static_url("components/codemirror/lib/codemirror.css") }}">
{{super()}}
{% endblock %}
{% block title %}{{page_title}}{% endblock %}
@ -152,7 +169,7 @@ data-server-root="{{server_root}}"
</div>
</div>
</div>
<div id="directory_readme" data-static-url="{{static_url("")}}"></div>
<div id="directory_readme"></div>
</div>
<div id="running" class="tab-pane">
<div id="running_toolbar" class="row">

@ -51,7 +51,9 @@ class TreeHandler(IPythonHandler):
breadcrumbs=breadcrumbs,
terminals_available=self.settings['terminals_available'],
server_root=self.settings['server_root_dir'],
shutdown_button=self.settings.get('shutdown_button', False)
shutdown_button=self.settings.get('shutdown_button', False),
mathjax_url=self.mathjax_url,
mathjax_config=self.mathjax_config
))
elif cm.file_exists(path):
# it's not a directory, we have redirecting to do

Loading…
Cancel
Save