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, "<") // use HTML entity for < |
|
110 | .replace(/</g, "<") // use HTML entity for < | |
112 | .replace(/>/g, ">") // use HTML entity for > |
|
111 | .replace(/>/g, ">") // use HTML entity for > | |
113 | ; |
|
112 | ; | |
114 |
if ( |
|
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 |
|
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