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