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