##// END OF EJS Templates
Merge pull request #4655 from minrk/marked-nbconvert...
Min RK -
r14794:07dbfbc2 merge
parent child Browse files
Show More
@@ -0,0 +1,54 b''
1 // Node.js script for markdown to html conversion
2 // This applies the same math extraction and marked settings
3 // that we use in the live notebook.
4
5 // IPython static_path dir relative to here:
6 var static_path = __dirname + "/../../html/static/";
7
8 var fs = require('fs');
9 var IPython;
10 // marked can be loaded with require,
11 // the others must be execfiled
12 var marked = require(static_path + 'components/marked/lib/marked.js');
13
14 eval(fs.readFileSync(static_path + "components/highlight.js/build/highlight.pack.js", 'utf8'));
15 eval(fs.readFileSync(static_path + "base/js/namespace.js", 'utf8'));
16
17 eval(fs.readFileSync(static_path + "base/js/utils.js", 'utf8'));
18 eval(fs.readFileSync(static_path + "notebook/js/mathjaxutils.js", 'utf8'));
19
20 // this is copied from notebook.main. Should it be moved somewhere we can reuse it?
21 marked.setOptions({
22 gfm : true,
23 tables: true,
24 langPrefix: "language-",
25 highlight: function(code, lang) {
26 if (!lang) {
27 // no language, no highlight
28 return code;
29 }
30 var highlighted;
31 try {
32 highlighted = hljs.highlight(lang, code, false);
33 } catch(err) {
34 highlighted = hljs.highlightAuto(code);
35 }
36 return highlighted.value;
37 }
38 });
39
40 // read the markdown from stdin
41 var md='';
42 process.stdin.on("data", function (data) {
43 md += data;
44 });
45
46 // perform the md2html transform once stdin is complete
47 process.stdin.on("end", function () {
48 var text_and_math = IPython.mathjaxutils.remove_math(md);
49 var text = text_and_math[0];
50 var math = text_and_math[1];
51 var html = marked.parser(marked.lexer(text));
52 html = IPython.mathjaxutils.replace_math(html, math);
53 process.stdout.write(html);
54 });
@@ -448,6 +448,10 b' IPython.utils = (function (IPython) {'
448
448
449 // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
449 // http://stackoverflow.com/questions/2400935/browser-detection-in-javascript
450 var browser = (function() {
450 var browser = (function() {
451 if (typeof navigator === 'undefined') {
452 // navigator undefined in node
453 return 'None';
454 }
451 var N= navigator.appName, ua= navigator.userAgent, tem;
455 var N= navigator.appName, ua= navigator.userAgent, tem;
452 var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
456 var M= ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
453 if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
457 if (M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
@@ -106,12 +106,11 b' IPython.mathjaxutils = (function (IPython) {'
106 // math, then push the math string onto the storage array.
106 // math, then push the math string onto the storage array.
107 // The preProcess function is called on all blocks if it has been passed in
107 // The preProcess function is called on all blocks if it has been passed in
108 var process_math = function (i, j, pre_process, math, blocks) {
108 var process_math = function (i, j, pre_process, math, blocks) {
109 var hub = MathJax.Hub;
110 var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&") // use HTML entity for &
109 var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&") // use HTML entity for &
111 .replace(/</g, "&lt;") // use HTML entity for <
110 .replace(/</g, "&lt;") // use HTML entity for <
112 .replace(/>/g, "&gt;") // use HTML entity for >
111 .replace(/>/g, "&gt;") // use HTML entity for >
113 ;
112 ;
114 if (hub.Browser.isMSIE) {
113 if (IPython.utils.browser === 'msie') {
115 block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n");
114 block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n");
116 }
115 }
117 while (j > i) {
116 while (j > i) {
@@ -133,10 +132,6 b' IPython.mathjaxutils = (function (IPython) {'
133 // (which will be a paragraph).
132 // (which will be a paragraph).
134 //
133 //
135 var remove_math = function (text) {
134 var remove_math = function (text) {
136 if (!window.MathJax) {
137 return [text, null];
138 }
139
140 var math = []; // stores math strings for later
135 var math = []; // stores math strings for later
141 var start;
136 var start;
142 var end;
137 var end;
@@ -241,9 +236,6 b' IPython.mathjaxutils = (function (IPython) {'
241 // and clear the math array (no need to keep it around).
236 // and clear the math array (no need to keep it around).
242 //
237 //
243 var replace_math = function (text, math) {
238 var replace_math = function (text, math) {
244 if (!window.MathJax) {
245 return text;
246 }
247 text = text.replace(/@@(\d+)@@/g, function (match, n) {
239 text = text.replace(/@@(\d+)@@/g, function (match, n) {
248 return math[n];
240 return math[n];
249 });
241 });
@@ -16,21 +16,33 b' markdown within Jinja templates.'
16 from __future__ import print_function
16 from __future__ import print_function
17
17
18 # Stdlib imports
18 # Stdlib imports
19 import sys
19 import os
20 import subprocess
20 import subprocess
21 from io import TextIOWrapper, BytesIO
21
22
23 # IPython imports
22 from IPython.nbconvert.utils.pandoc import pandoc
24 from IPython.nbconvert.utils.pandoc import pandoc
25 from IPython.nbconvert.utils.exceptions import ConversionException
26 from IPython.utils.process import find_cmd, FindCmdError
27 from IPython.utils.py3compat import cast_bytes
23
28
24 #-----------------------------------------------------------------------------
29 #-----------------------------------------------------------------------------
25 # Functions
30 # Functions
26 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
32 marked = os.path.join(os.path.dirname(__file__), "marked.js")
27
33
28 __all__ = [
34 __all__ = [
29 'markdown2html',
35 'markdown2html',
36 'markdown2html_pandoc',
37 'markdown2html_marked',
30 'markdown2latex',
38 'markdown2latex',
31 'markdown2rst'
39 'markdown2rst',
32 ]
40 ]
33
41
42 class NodeJSMissing(ConversionException):
43 """Exception raised when node.js is missing."""
44 pass
45
34 def markdown2latex(source):
46 def markdown2latex(source):
35 """Convert a markdown string to LaTeX via pandoc.
47 """Convert a markdown string to LaTeX via pandoc.
36
48
@@ -49,11 +61,26 b' def markdown2latex(source):'
49 """
61 """
50 return pandoc(source, 'markdown', 'latex')
62 return pandoc(source, 'markdown', 'latex')
51
63
52
64 def markdown2html_pandoc(source):
53 def markdown2html(source):
54 """Convert a markdown string to HTML via pandoc"""
65 """Convert a markdown string to HTML via pandoc"""
55 return pandoc(source, 'markdown', 'html', extra_args=['--mathjax'])
66 return pandoc(source, 'markdown', 'html', extra_args=['--mathjax'])
56
67
68 def markdown2html_marked(source, encoding='utf-8'):
69 """Convert a markdown string to HTML via marked"""
70 command = ['node', marked]
71 try:
72 p = subprocess.Popen(command,
73 stdin=subprocess.PIPE, stdout=subprocess.PIPE
74 )
75 except OSError as e:
76 raise NodeJSMissing(
77 "The command '%s' returned an error: %s.\n" % (" ".join(command), e) +
78 "Please check that Node.js is installed."
79 )
80 out, _ = p.communicate(cast_bytes(source, encoding))
81 out = TextIOWrapper(BytesIO(out), encoding, 'replace').read()
82 return out.rstrip('\n')
83
57 def markdown2rst(source):
84 def markdown2rst(source):
58 """Convert a markdown string to LaTeX via pandoc.
85 """Convert a markdown string to LaTeX via pandoc.
59
86
@@ -72,3 +99,9 b' def markdown2rst(source):'
72 """
99 """
73 return pandoc(source, 'markdown', 'rst')
100 return pandoc(source, 'markdown', 'rst')
74
101
102 try:
103 find_cmd('node')
104 except FindCmdError:
105 markdown2html = markdown2html_pandoc
106 else:
107 markdown2html = markdown2html_marked
@@ -164,6 +164,7 b' def find_package_data():'
164 'IPython.qt.console' : ['resources/icon/*.svg'],
164 'IPython.qt.console' : ['resources/icon/*.svg'],
165 'IPython.nbconvert' : nbconvert_templates +
165 'IPython.nbconvert' : nbconvert_templates +
166 ['tests/files/*.*', 'exporters/tests/files/*.*'],
166 ['tests/files/*.*', 'exporters/tests/files/*.*'],
167 'IPython.nbconvert.filters' : ['marked.js'],
167 'IPython.nbformat' : ['tests/*.ipynb']
168 'IPython.nbformat' : ['tests/*.ipynb']
168 }
169 }
169 return package_data
170 return package_data
General Comments 0
You need to be logged in to leave comments. Login now