Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50654 views
1
//----------------------------------------------------------------------------
2
// Copyright (C) 2008-2012 The IPython Development Team
3
//
4
// Distributed under the terms of the BSD License. The full license is in
5
// the file COPYING, distributed as part of this software.
6
//----------------------------------------------------------------------------
7
8
//============================================================================
9
// MathJax utility functions
10
//============================================================================
11
12
13
IPython.namespace('IPython.mathjaxutils');
14
15
IPython.mathjaxutils = (function (IPython) {
16
"use strict";
17
18
var init = function () {
19
if (window.MathJax) {
20
// MathJax loaded
21
MathJax.Hub.Config({
22
tex2jax: {
23
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
24
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
25
processEscapes: true,
26
processEnvironments: true
27
},
28
// Center justify equations in code and markdown cells. Elsewhere
29
// we use CSS to left justify single line equations in code cells.
30
displayAlign: 'center',
31
"HTML-CSS": {
32
styles: {'.MathJax_Display': {"margin": 0}},
33
linebreaks: { automatic: true }
34
}
35
});
36
MathJax.Hub.Configured();
37
} else if (window.mathjax_url !== "") {
38
// Don't have MathJax, but should. Show dialog.
39
var message = $('<div/>')
40
.append(
41
$("<p/></p>").addClass('dialog').text(
42
"Math/LaTeX rendering will be disabled."
43
)
44
).append(
45
$("<p></p>").addClass('dialog').text(
46
"If you have administrative access to the notebook server and" +
47
" a working internet connection, you can install a local copy" +
48
" of MathJax for offline use with the following command on the server" +
49
" at a Python or IPython prompt:"
50
)
51
).append(
52
$("<pre></pre>").addClass('dialog').text(
53
">>> from IPython.external import mathjax; mathjax.install_mathjax()"
54
)
55
).append(
56
$("<p></p>").addClass('dialog').text(
57
"This will try to install MathJax into the IPython source directory."
58
)
59
).append(
60
$("<p></p>").addClass('dialog').text(
61
"If IPython is installed to a location that requires" +
62
" administrative privileges to write, you will need to make this call as" +
63
" an administrator, via 'sudo'."
64
)
65
).append(
66
$("<p></p>").addClass('dialog').text(
67
"When you start the notebook server, you can instruct it to disable MathJax support altogether:"
68
)
69
).append(
70
$("<pre></pre>").addClass('dialog').text(
71
"$ ipython notebook --no-mathjax"
72
)
73
).append(
74
$("<p></p>").addClass('dialog').text(
75
"which will prevent this dialog from appearing."
76
)
77
);
78
IPython.dialog.modal({
79
title : "Failed to retrieve MathJax from '" + window.mathjax_url + "'",
80
body : message,
81
buttons : {
82
OK : {class: "btn-danger"}
83
}
84
});
85
}
86
};
87
88
// Some magic for deferring mathematical expressions to MathJax
89
// by hiding them from the Markdown parser.
90
// Some of the code here is adapted with permission from Davide Cervone
91
// under the terms of the Apache2 license governing the MathJax project.
92
// Other minor modifications are also due to StackExchange and are used with
93
// permission.
94
95
var inline = "$"; // the inline math delimiter
96
97
// MATHSPLIT contains the pattern for math delimiters and special symbols
98
// needed for searching for math in the text input.
99
var MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
100
101
// The math is in blocks i through j, so
102
// collect it into one block and clear the others.
103
// Replace &, <, and > by named entities.
104
// For IE, put <br> at the ends of comments since IE removes \n.
105
// Clear the current math positions and store the index of the
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
108
var process_math = function (i, j, pre_process, math, blocks) {
109
var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&amp;") // use HTML entity for &
110
.replace(/</g, "&lt;") // use HTML entity for <
111
.replace(/>/g, "&gt;") // use HTML entity for >
112
;
113
if (IPython.utils.browser === 'msie') {
114
block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n");
115
}
116
while (j > i) {
117
blocks[j] = "";
118
j--;
119
}
120
blocks[i] = "@@" + math.length + "@@"; // replace the current block text with a unique tag to find later
121
if (pre_process){
122
block = pre_process(block);
123
}
124
math.push(block);
125
return blocks;
126
};
127
128
// Break up the text into its component parts and search
129
// through them for math delimiters, braces, linebreaks, etc.
130
// Math delimiters must match and braces must balance.
131
// Don't allow math to pass through a double linebreak
132
// (which will be a paragraph).
133
//
134
var remove_math = function (text) {
135
var math = []; // stores math strings for later
136
var start;
137
var end;
138
var last;
139
var braces;
140
141
// Except for extreme edge cases, this should catch precisely those pieces of the markdown
142
// source that will later be turned into code spans. While MathJax will not TeXify code spans,
143
// we still have to consider them at this point; the following issue has happened several times:
144
//
145
// `$foo` and `$bar` are varibales. --> <code>$foo ` and `$bar</code> are variables.
146
147
var hasCodeSpans = /`/.test(text),
148
de_tilde;
149
if (hasCodeSpans) {
150
text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function (wholematch) {
151
return wholematch.replace(/\$/g, "~D");
152
});
153
de_tilde = function (text) {
154
return text.replace(/~([TD])/g, function (wholematch, character) {
155
return { T: "~", D: "$" }[character];
156
});
157
};
158
} else {
159
de_tilde = function (text) { return text; };
160
}
161
162
var blocks = IPython.utils.regex_split(text.replace(/\r\n?/g, "\n"),MATHSPLIT);
163
164
for (var i = 1, m = blocks.length; i < m; i += 2) {
165
var block = blocks[i];
166
if (block.charAt(0) === "@") {
167
//
168
// Things that look like our math markers will get
169
// stored and then retrieved along with the math.
170
//
171
blocks[i] = "@@" + math.length + "@@";
172
math.push(block);
173
}
174
else if (start) {
175
//
176
// If we are in math, look for the end delimiter,
177
// but don't go past double line breaks, and
178
// and balance braces within the math.
179
//
180
if (block === end) {
181
if (braces) {
182
last = i;
183
}
184
else {
185
blocks = process_math(start, i, de_tilde, math, blocks);
186
start = null;
187
end = null;
188
last = null;
189
}
190
}
191
else if (block.match(/\n.*\n/)) {
192
if (last) {
193
i = last;
194
blocks = process_math(start, i, de_tilde, math, blocks);
195
}
196
start = null;
197
end = null;
198
last = null;
199
braces = 0;
200
}
201
else if (block === "{") {
202
braces++;
203
}
204
else if (block === "}" && braces) {
205
braces--;
206
}
207
}
208
else {
209
//
210
// Look for math start delimiters and when
211
// found, set up the end delimiter.
212
//
213
if (block === inline || block === "$$") {
214
start = i;
215
end = block;
216
braces = 0;
217
}
218
else if (block.substr(1, 5) === "begin") {
219
start = i;
220
end = "\\end" + block.substr(6);
221
braces = 0;
222
}
223
}
224
}
225
if (last) {
226
blocks = process_math(start, last, de_tilde, math, blocks);
227
start = null;
228
end = null;
229
last = null;
230
}
231
return [de_tilde(blocks.join("")), math];
232
};
233
234
//
235
// Put back the math strings that were saved,
236
// and clear the math array (no need to keep it around).
237
//
238
var replace_math = function (text, math) {
239
text = text.replace(/@@(\d+)@@/g, function (match, n) {
240
return math[n];
241
});
242
return text;
243
};
244
245
return {
246
init : init,
247
remove_math : remove_math,
248
replace_math : replace_math
249
};
250
251
}(IPython));
252
253