##// END OF EJS Templates
Improved MathJax, missing callback workaround...
Aron Ahmadia -
Show More
@@ -1,220 +1,212 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2008-2011 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 // Cell
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13
14 14 var utils = IPython.utils;
15 15
16 16
17 17 var Cell = function () {
18 18 this.placeholder = this.placeholder || '';
19 19 this.read_only = false;
20 20 this.selected = false;
21 21 this.element = null;
22 22 this.metadata = {};
23 23 // load this from metadata later ?
24 24 this.user_highlight == 'auto';
25 25 this.create_element();
26 26 if (this.element !== null) {
27 27 this.element.data("cell", this);
28 28 this.bind_events();
29 29 }
30 30 this.cell_id = utils.uuid();
31 31 };
32 32
33 33
34 34 // Subclasses must implement create_element.
35 35 Cell.prototype.create_element = function () {};
36 36
37 37
38 38 Cell.prototype.bind_events = function () {
39 39 var that = this;
40 40 // We trigger events so that Cell doesn't have to depend on Notebook.
41 41 that.element.click(function (event) {
42 42 if (that.selected === false) {
43 43 $([IPython.events]).trigger('select.Cell', {'cell':that});
44 44 }
45 45 });
46 46 that.element.focusin(function (event) {
47 47 if (that.selected === false) {
48 48 $([IPython.events]).trigger('select.Cell', {'cell':that});
49 49 }
50 50 });
51 51 };
52 52
53 53
54 // typeset with MathJax if MathJax is available
55 Cell.prototype.typeset = function () {
56 if (window.MathJax){
57 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
58 }
59 };
60
61
62 54 Cell.prototype.select = function () {
63 55 this.element.addClass('ui-widget-content ui-corner-all');
64 56 this.selected = true;
65 57 };
66 58
67 59
68 60 Cell.prototype.unselect = function () {
69 61 this.element.removeClass('ui-widget-content ui-corner-all');
70 62 this.selected = false;
71 63 };
72 64
73 65
74 66 Cell.prototype.get_text = function () {
75 67 };
76 68
77 69
78 70 Cell.prototype.set_text = function (text) {
79 71 };
80 72
81 73
82 74 Cell.prototype.refresh = function () {
83 75 this.code_mirror.refresh();
84 76 };
85 77
86 78
87 79 Cell.prototype.edit = function () {
88 80 };
89 81
90 82
91 83 Cell.prototype.render = function () {
92 84 };
93 85
94 86
95 87 Cell.prototype.toJSON = function () {
96 88 var data = {};
97 89 data.metadata = this.metadata;
98 90 return data;
99 91 };
100 92
101 93
102 94 Cell.prototype.fromJSON = function (data) {
103 95 if (data.metadata !== undefined) {
104 96 this.metadata = data.metadata;
105 97 }
106 98 };
107 99
108 100
109 101 Cell.prototype.is_splittable = function () {
110 102 return true;
111 103 };
112 104
113 105
114 106 Cell.prototype.get_pre_cursor = function () {
115 107 var cursor = this.code_mirror.getCursor();
116 108 var text = this.code_mirror.getRange({line:0,ch:0}, cursor);
117 109 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
118 110 return text;
119 111 }
120 112
121 113
122 114 Cell.prototype.get_post_cursor = function () {
123 115 var cursor = this.code_mirror.getCursor();
124 116 var last_line_num = this.code_mirror.lineCount()-1;
125 117 var last_line_len = this.code_mirror.getLine(last_line_num).length;
126 118 var end = {line:last_line_num, ch:last_line_len}
127 119 var text = this.code_mirror.getRange(cursor, end);
128 120 text = text.replace(/^\n+/, '').replace(/\n+$/, '');
129 121 return text;
130 122 };
131 123
132 124
133 125 Cell.prototype.grow = function(element) {
134 126 // Grow the cell by hand. This is used upon reloading from JSON, when the
135 127 // autogrow handler is not called.
136 128 var dom = element.get(0);
137 129 var lines_count = 0;
138 130 // modified split rule from
139 131 // http://stackoverflow.com/questions/2035910/how-to-get-the-number-of-lines-in-a-textarea/2036424#2036424
140 132 var lines = dom.value.split(/\r|\r\n|\n/);
141 133 lines_count = lines.length;
142 134 if (lines_count >= 1) {
143 135 dom.rows = lines_count;
144 136 } else {
145 137 dom.rows = 1;
146 138 }
147 139 };
148 140
149 141
150 142 Cell.prototype.toggle_line_numbers = function () {
151 143 if (this.code_mirror.getOption('lineNumbers') == false) {
152 144 this.code_mirror.setOption('lineNumbers', true);
153 145 } else {
154 146 this.code_mirror.setOption('lineNumbers', false);
155 147 }
156 148 this.code_mirror.refresh();
157 149 };
158 150
159 151 Cell.prototype.force_highlight = function(mode) {
160 152 this.user_highlight = mode;
161 153 this.auto_highlight();
162 154 };
163 155
164 156 Cell.prototype._auto_highlight = function (modes) {
165 157 //Here we handle manually selected modes
166 158 if( this.user_highlight != undefined && this.user_highlight != 'auto' )
167 159 {
168 160 var mode = this.user_highlight;
169 161 CodeMirror.autoLoadMode(this.code_mirror, mode);
170 162 this.code_mirror.setOption('mode', mode);
171 163 return;
172 164 }
173 165 var first_line = this.code_mirror.getLine(0);
174 166 // loop on every pairs
175 167 for( var mode in modes) {
176 168 var regs = modes[mode]['reg'];
177 169 // only one key every time but regexp can't be keys...
178 170 for(var reg in regs ) {
179 171 // here we handle non magic_modes
180 172 if(first_line.match(regs[reg]) != null) {
181 173 if (mode.search('magic_') != 0) {
182 174 this.code_mirror.setOption('mode',mode);
183 175 CodeMirror.autoLoadMode(this.code_mirror, mode);
184 176 return;
185 177 }
186 178 var open = modes[mode]['open']|| "%%";
187 179 var close = modes[mode]['close']|| "%%end";
188 180 var mmode = mode;
189 181 mode = mmode.substr(6);
190 182 CodeMirror.autoLoadMode(this.code_mirror, mode);
191 183 // create on the fly a mode that swhitch between
192 184 // plain/text and smth else otherwise `%%` is
193 185 // source of some highlight issues.
194 186 // we use patchedGetMode to circumvent a bug in CM
195 187 CodeMirror.defineMode(mmode , function(config) {
196 188 return CodeMirror.multiplexingMode(
197 189 CodeMirror.patchedGetMode(config, 'text/plain'),
198 190 // always set someting on close
199 191 {open: open, close: close,
200 192 mode: CodeMirror.patchedGetMode(config, mode),
201 193 delimStyle: "delimit"
202 194 }
203 195 );
204 196 });
205 197 this.code_mirror.setOption('mode', mmode);
206 198 return;
207 199 }
208 200 }
209 201 }
210 202 // fallback on default (python)
211 203 var default_mode = this.default_mode || 'text/plain';
212 204 this.code_mirror.setOption('mode', default_mode);
213 205 };
214 206
215 207 IPython.Cell = Cell;
216 208
217 209 return IPython;
218 210
219 211 }(IPython));
220 212
@@ -1,243 +1,237 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 IPython.namespace('IPython.mathjaxutils');
13 13
14 14 IPython.mathjaxutils = (function (IPython) {
15 15
16 16 var init = function () {
17 17 if (window.MathJax) {
18 18 // MathJax loaded
19 MathJax.Hub.Config({
20 TeX: { equationNumbers: { autoNumber: "AMS", useLabelIds: true } },
21 tex2jax: {
22 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
23 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
24 processEnvironments: true
25 },
26 displayAlign: 'left', // Change this to 'center' to center equations.
27 "HTML-CSS": {
28 styles: {'.MathJax_Display': {"margin": 0}}
29 }
30 });
31 19 } else if (window.mathjax_url != "") {
32 20 // Don't have MathJax, but should. Show dialog.
33 21 var dialog = $('<div></div>')
34 22 .append(
35 23 $("<p></p>").addClass('dialog').html(
36 24 "Math/LaTeX rendering will be disabled."
37 25 )
38 26 ).append(
39 27 $("<p></p>").addClass('dialog').html(
40 28 "If you have administrative access to the notebook server and" +
41 29 " a working internet connection, you can install a local copy" +
42 30 " of MathJax for offline use with the following command on the server" +
43 31 " at a Python or IPython prompt:"
44 32 )
45 33 ).append(
46 34 $("<pre></pre>").addClass('dialog').html(
47 35 ">>> from IPython.external import mathjax; mathjax.install_mathjax()"
48 36 )
49 37 ).append(
50 38 $("<p></p>").addClass('dialog').html(
51 39 "This will try to install MathJax into the IPython source directory."
52 40 )
53 41 ).append(
54 42 $("<p></p>").addClass('dialog').html(
55 43 "If IPython is installed to a location that requires" +
56 44 " administrative privileges to write, you will need to make this call as" +
57 45 " an administrator, via 'sudo'."
58 46 )
59 47 ).append(
60 48 $("<p></p>").addClass('dialog').html(
61 49 "When you start the notebook server, you can instruct it to disable MathJax support altogether:"
62 50 )
63 51 ).append(
64 52 $("<pre></pre>").addClass('dialog').html(
65 53 "$ ipython notebook --no-mathjax"
66 54 )
67 55 ).append(
68 56 $("<p></p>").addClass('dialog').html(
69 57 "which will prevent this dialog from appearing."
70 58 )
71 59 ).dialog({
72 60 title: "Failed to retrieve MathJax from '" + window.mathjax_url + "'",
73 61 width: "70%",
74 62 modal: true,
75 63 })
76 64 } else {
77 65 // No MathJax, but none expected. No dialog.
78 66 };
79 67 };
80 68
81 69 // Some magic for deferring mathematical expressions to MathJax
82 70 // by hiding them from the Markdown parser.
83 71 // Some of the code here is adapted with permission from Davide Cervone
84 72 // under the terms of the Apache2 license governing the MathJax project.
85 73 // Other minor modifications are also due to StackExchange and are used with
86 74 // permission.
87 75
88 76 var inline = "$"; // the inline math delimiter
89 77 var blocks, start, end, last, braces; // used in searching for math
90 78 var math; // stores math until pagedown (Markdown parser) is done
91 79 var HUB = MathJax.Hub;
92 80
93 81 // MATHSPLIT contains the pattern for math delimiters and special symbols
94 82 // needed for searching for math in the text input.
95 83 var MATHSPLIT = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
96 84
97 85 // The math is in blocks i through j, so
98 86 // collect it into one block and clear the others.
99 87 // Replace &, <, and > by named entities.
100 88 // For IE, put <br> at the ends of comments since IE removes \n.
101 89 // Clear the current math positions and store the index of the
102 90 // math, then push the math string onto the storage array.
103 91 // The preProcess function is called on all blocks if it has been passed in
104 92 var process_math = function (i, j, pre_process) {
105 93 var block = blocks.slice(i, j + 1).join("").replace(/&/g, "&amp;") // use HTML entity for &
106 94 .replace(/</g, "&lt;") // use HTML entity for <
107 95 .replace(/>/g, "&gt;") // use HTML entity for >
108 96 ;
109 97 if (HUB.Browser.isMSIE) {
110 98 block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n")
111 99 }
112 100 while (j > i) {
113 101 blocks[j] = "";
114 102 j--;
115 103 }
116 104 blocks[i] = "@@" + math.length + "@@"; // replace the current block text with a unique tag to find later
117 105 if (pre_process)
118 106 block = pre_process(block);
119 107 math.push(block);
120 108 start = end = last = null;
121 109 }
122 110
123 111 // Break up the text into its component parts and search
124 112 // through them for math delimiters, braces, linebreaks, etc.
125 113 // Math delimiters must match and braces must balance.
126 114 // Don't allow math to pass through a double linebreak
127 115 // (which will be a paragraph).
128 116 //
129 117 var remove_math = function (text) {
130 118 start = end = last = null; // for tracking math delimiters
131 119 math = []; // stores math strings for later
132 120
133 121 // Except for extreme edge cases, this should catch precisely those pieces of the markdown
134 122 // source that will later be turned into code spans. While MathJax will not TeXify code spans,
135 123 // we still have to consider them at this point; the following issue has happened several times:
136 124 //
137 125 // `$foo` and `$bar` are varibales. --> <code>$foo ` and `$bar</code> are variables.
138 126
139 127 var hasCodeSpans = /`/.test(text),
140 128 de_tilde;
141 129 if (hasCodeSpans) {
142 130 text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function (wholematch) {
143 131 return wholematch.replace(/\$/g, "~D");
144 132 });
145 133 de_tilde = function (text) { return text.replace(/~([TD])/g, function (wholematch, character) { return { T: "~", D: "$" }[character]; }) };
146 134 } else {
147 135 de_tilde = function (text) { return text; };
148 136 }
149 137
150 138 blocks = IPython.utils.regex_split(text.replace(/\r\n?/g, "\n"),MATHSPLIT);
151 139
152 140 for (var i = 1, m = blocks.length; i < m; i += 2) {
153 141 var block = blocks[i];
154 142 if (block.charAt(0) === "@") {
155 143 //
156 144 // Things that look like our math markers will get
157 145 // stored and then retrieved along with the math.
158 146 //
159 147 blocks[i] = "@@" + math.length + "@@";
160 148 math.push(block);
161 149 }
162 150 else if (start) {
163 151 //
164 152 // If we are in math, look for the end delimiter,
165 153 // but don't go past double line breaks, and
166 154 // and balance braces within the math.
167 155 //
168 156 if (block === end) {
169 157 if (braces) {
170 158 last = i
171 159 }
172 160 else {
173 161 process_math(start, i, de_tilde)
174 162 }
175 163 }
176 164 else if (block.match(/\n.*\n/)) {
177 165 if (last) {
178 166 i = last;
179 167 process_math(start, i, de_tilde)
180 168 }
181 169 start = end = last = null;
182 170 braces = 0;
183 171 }
184 172 else if (block === "{") {
185 173 braces++
186 174 }
187 175 else if (block === "}" && braces) {
188 176 braces--
189 177 }
190 178 }
191 179 else {
192 180 //
193 181 // Look for math start delimiters and when
194 182 // found, set up the end delimiter.
195 183 //
196 184 if (block === inline || block === "$$") {
197 185 start = i;
198 186 end = block;
199 187 braces = 0;
200 188 }
201 189 else if (block.substr(1, 5) === "begin") {
202 190 start = i;
203 191 end = "\\end" + block.substr(6);
204 192 braces = 0;
205 193 }
206 194 }
207 195 }
208 196 if (last) {
209 197 process_math(start, last, de_tilde)
210 198 }
211 199 return de_tilde(blocks.join(""));
212 200 }
213 201
214 202 //
215 203 // Put back the math strings that were saved,
216 204 // and clear the math array (no need to keep it around).
217 205 //
218 206 var replace_math = function (text) {
219 207 text = text.replace(/@@(\d+)@@/g, function (match, n) {
220 208 return math[n]
221 209 });
222 210 math = null;
223 211 return text;
224 212 }
225 213
226 214 var queue_render = function () {
227 215 // see https://groups.google.com/forum/?fromgroups=#!topic/mathjax-users/cpwy5eCH1ZQ
216 var jax = MathJax.Hub.getAllJax();
217
228 218 MathJax.Hub.Queue(
229 ["resetEquationNumbers",MathJax.InputJax.TeX],
219 function () {
220 if (MathJax.InputJax.TeX.resetEquationNumbers) {
221 MathJax.InputJax.TeX.resetEquationNumbers();
222 }
223 },
230 224 ["PreProcess",MathJax.Hub],
231 225 ["Reprocess",MathJax.Hub]
232 226 );
233 227 }
234 228
235 229 return {
236 230 init : init,
237 231 process_math : process_math,
238 232 remove_math : remove_math,
239 233 replace_math : replace_math,
240 234 queue_render : queue_render
241 235 };
242 236
243 237 }(IPython)); No newline at end of file
@@ -1,421 +1,420 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 // TextCell
10 10 //============================================================================
11 11
12 12 var IPython = (function (IPython) {
13 13
14 14 // TextCell base class
15 15 var key = IPython.utils.keycodes;
16 16
17 17 var TextCell = function () {
18 18 this.code_mirror_mode = this.code_mirror_mode || 'htmlmixed';
19 19 IPython.Cell.apply(this, arguments);
20 20 this.rendered = false;
21 21 this.cell_type = this.cell_type || 'text';
22 22 };
23 23
24 24
25 25 TextCell.prototype = new IPython.Cell();
26 26
27 27
28 28 TextCell.prototype.create_element = function () {
29 29 var cell = $("<div>").addClass('cell text_cell border-box-sizing');
30 30 cell.attr('tabindex','2');
31 31 var input_area = $('<div/>').addClass('text_cell_input border-box-sizing');
32 32 this.code_mirror = CodeMirror(input_area.get(0), {
33 33 indentUnit : 4,
34 34 mode: this.code_mirror_mode,
35 35 theme: 'default',
36 36 value: this.placeholder,
37 37 readOnly: this.read_only,
38 38 lineWrapping : true,
39 39 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
40 40 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
41 41 });
42 42 // The tabindex=-1 makes this div focusable.
43 43 var render_area = $('<div/>').addClass('text_cell_render border-box-sizing').
44 44 addClass('rendered_html').attr('tabindex','-1');
45 45 cell.append(input_area).append(render_area);
46 46 this.element = cell;
47 47 };
48 48
49 49
50 50 TextCell.prototype.bind_events = function () {
51 51 IPython.Cell.prototype.bind_events.apply(this);
52 52 var that = this;
53 53 this.element.keydown(function (event) {
54 54 if (event.which === 13 && !event.shiftKey) {
55 55 if (that.rendered) {
56 56 that.edit();
57 57 return false;
58 58 };
59 59 };
60 60 });
61 61 this.element.dblclick(function () {
62 62 that.edit();
63 63 });
64 64 };
65 65
66 66
67 67 TextCell.prototype.handle_codemirror_keyevent = function (editor, event) {
68 68 // This method gets called in CodeMirror's onKeyDown/onKeyPress
69 69 // handlers and is used to provide custom key handling. Its return
70 70 // value is used to determine if CodeMirror should ignore the event:
71 71 // true = ignore, false = don't ignore.
72 72
73 73 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
74 74 // Always ignore shift-enter in CodeMirror as we handle it.
75 75 return true;
76 76 }
77 77 return false;
78 78 };
79 79
80 80
81 81 TextCell.prototype.select = function () {
82 82 IPython.Cell.prototype.select.apply(this);
83 83 var output = this.element.find("div.text_cell_render");
84 84 output.trigger('focus');
85 85 };
86 86
87 87
88 88 TextCell.prototype.unselect = function() {
89 89 // render on selection of another cell
90 90 this.render();
91 91 IPython.Cell.prototype.unselect.apply(this);
92 92 };
93 93
94 94
95 95 TextCell.prototype.edit = function () {
96 96 if ( this.read_only ) return;
97 97 if (this.rendered === true) {
98 98 var text_cell = this.element;
99 99 var output = text_cell.find("div.text_cell_render");
100 100 output.hide();
101 101 text_cell.find('div.text_cell_input').show();
102 102 this.code_mirror.refresh();
103 103 this.code_mirror.focus();
104 104 // We used to need an additional refresh() after the focus, but
105 105 // it appears that this has been fixed in CM. This bug would show
106 106 // up on FF when a newly loaded markdown cell was edited.
107 107 this.rendered = false;
108 108 if (this.get_text() === this.placeholder) {
109 109 this.set_text('');
110 110 this.refresh();
111 111 }
112 112 }
113 113 };
114 114
115 115
116 116 // Subclasses must define render.
117 117 TextCell.prototype.render = function () {};
118 118
119 119
120 120 TextCell.prototype.get_text = function() {
121 121 return this.code_mirror.getValue();
122 122 };
123 123
124 124
125 125 TextCell.prototype.set_text = function(text) {
126 126 this.code_mirror.setValue(text);
127 127 this.code_mirror.refresh();
128 128 };
129 129
130 130
131 131 TextCell.prototype.get_rendered = function() {
132 132 return this.element.find('div.text_cell_render').html();
133 133 };
134 134
135 135
136 136 TextCell.prototype.set_rendered = function(text) {
137 137 this.element.find('div.text_cell_render').html(text);
138 138 };
139 139
140 140
141 141 TextCell.prototype.at_top = function () {
142 142 if (this.rendered) {
143 143 return true;
144 144 } else {
145 145 return false;
146 146 }
147 147 };
148 148
149 149
150 150 TextCell.prototype.at_bottom = function () {
151 151 if (this.rendered) {
152 152 return true;
153 153 } else {
154 154 return false;
155 155 }
156 156 };
157 157
158 158
159 159 TextCell.prototype.fromJSON = function (data) {
160 160 IPython.Cell.prototype.fromJSON.apply(this, arguments);
161 161 if (data.cell_type === this.cell_type) {
162 162 if (data.source !== undefined) {
163 163 this.set_text(data.source);
164 164 // make this value the starting point, so that we can only undo
165 165 // to this state, instead of a blank cell
166 166 this.code_mirror.clearHistory();
167 167 this.set_rendered(data.rendered || '');
168 168 this.rendered = false;
169 169 this.render();
170 170 }
171 171 }
172 172 };
173 173
174 174
175 175 TextCell.prototype.toJSON = function () {
176 176 var data = IPython.Cell.prototype.toJSON.apply(this);
177 177 data.cell_type = this.cell_type;
178 178 data.source = this.get_text();
179 179 return data;
180 180 };
181 181
182 182
183 183 // HTMLCell
184 184
185 185 var HTMLCell = function () {
186 186 this.placeholder = "Type <strong>HTML</strong> and LaTeX: $\\alpha^2$";
187 187 IPython.TextCell.apply(this, arguments);
188 188 this.cell_type = 'html';
189 189 };
190 190
191 191
192 192 HTMLCell.prototype = new TextCell();
193 193
194 194
195 195 HTMLCell.prototype.render = function () {
196 196 if (this.rendered === false) {
197 197 var text = this.get_text();
198 198 if (text === "") { text = this.placeholder; }
199 199 this.set_rendered(text);
200 200 this.typeset();
201 201 this.element.find('div.text_cell_input').hide();
202 202 this.element.find("div.text_cell_render").show();
203 203 this.rendered = true;
204 204 }
205 205 };
206 206
207 207
208 208 // MarkdownCell
209 209
210 210 var MarkdownCell = function () {
211 211 this.placeholder = "Type *Markdown* and LaTeX: $\\alpha^2$";
212 212 IPython.TextCell.apply(this, arguments);
213 213 this.cell_type = 'markdown';
214 214 };
215 215
216 216
217 217 MarkdownCell.prototype = new TextCell();
218 218
219 219
220 220 MarkdownCell.prototype.render = function () {
221 221 if (this.rendered === false) {
222 222 var text = this.get_text();
223 223 if (text === "") { text = this.placeholder; }
224
225 text = IPython.mathjaxutils.remove_math(text)
226 var html = IPython.markdown_converter.makeHtml(text);
227 html = IPython.mathjaxutils.replace_math(html)
228
229 try {
230 this.set_rendered(html);
231 } catch (e) {
232 console.log("Error running Javascript in Markdown:");
233 console.log(e);
234 this.set_rendered($("<div/>").addClass("js-error").html(
235 "Error rendering Markdown!<br/>" + e.toString())
236 );
224 else {
225 text = IPython.mathjaxutils.remove_math(text)
226 var html = IPython.markdown_converter.makeHtml(text);
227 html = IPython.mathjaxutils.replace_math(html)
228 try {
229 this.set_rendered(html);
230 } catch (e) {
231 console.log("Error running Javascript in Markdown:");
232 console.log(e);
233 this.set_rendered($("<div/>").addClass("js-error").html(
234 "Error rendering Markdown!<br/>" + e.toString())
235 );
236 }
237 this.element.find('div.text_cell_input').hide();
238 this.element.find("div.text_cell_render").show();
239 var code_snippets = this.element.find("pre > code");
240 code_snippets.replaceWith(function () {
241 var code = $(this).html();
242 /* Substitute br for newlines and &nbsp; for spaces
243 before highlighting, since prettify doesn't
244 preserve those on all browsers */
245 code = code.replace(/(\r\n|\n|\r)/gm, "<br/>");
246 code = code.replace(/ /gm, '&nbsp;');
247 code = prettyPrintOne(code);
248
249 return '<code class="prettyprint">' + code + '</code>';
250 });
251
252 IPython.mathjaxutils.queue_render()
237 253 }
238 this.typeset()
239 this.element.find('div.text_cell_input').hide();
240 this.element.find("div.text_cell_render").show();
241 var code_snippets = this.element.find("pre > code");
242 code_snippets.replaceWith(function () {
243 var code = $(this).html();
244 /* Substitute br for newlines and &nbsp; for spaces
245 before highlighting, since prettify doesn't
246 preserve those on all browsers */
247 code = code.replace(/(\r\n|\n|\r)/gm, "<br/>");
248 code = code.replace(/ /gm, '&nbsp;');
249 code = prettyPrintOne(code);
250
251 return '<code class="prettyprint">' + code + '</code>';
252 });
253
254 IPython.mathjaxutils.queue_render()
255 254 this.rendered = true;
256 255 }
257 256 };
258 257
259 258
260 259 // RawCell
261 260
262 261 var RawCell = function () {
263 262 this.placeholder = "Type plain text and LaTeX: $\\alpha^2$";
264 263 this.code_mirror_mode = 'rst';
265 264 IPython.TextCell.apply(this, arguments);
266 265 this.cell_type = 'raw';
267 266 var that = this
268 267
269 268 this.element.focusout(
270 269 function() { that.auto_highlight(); }
271 270 );
272 271 };
273 272
274 273
275 274 RawCell.prototype = new TextCell();
276 275
277 276 RawCell.prototype.auto_highlight = function () {
278 277 this._auto_highlight(IPython.config.raw_cell_highlight);
279 278 };
280 279
281 280 RawCell.prototype.render = function () {
282 281 this.rendered = true;
283 282 this.edit();
284 283 };
285 284
286 285
287 286 RawCell.prototype.handle_codemirror_keyevent = function (editor, event) {
288 287 // This method gets called in CodeMirror's onKeyDown/onKeyPress
289 288 // handlers and is used to provide custom key handling. Its return
290 289 // value is used to determine if CodeMirror should ignore the event:
291 290 // true = ignore, false = don't ignore.
292 291
293 292 var that = this;
294 293 if (event.which === key.UPARROW && event.type === 'keydown') {
295 294 // If we are not at the top, let CM handle the up arrow and
296 295 // prevent the global keydown handler from handling it.
297 296 if (!that.at_top()) {
298 297 event.stop();
299 298 return false;
300 299 } else {
301 300 return true;
302 301 };
303 302 } else if (event.which === key.DOWNARROW && event.type === 'keydown') {
304 303 // If we are not at the bottom, let CM handle the down arrow and
305 304 // prevent the global keydown handler from handling it.
306 305 if (!that.at_bottom()) {
307 306 event.stop();
308 307 return false;
309 308 } else {
310 309 return true;
311 310 };
312 311 };
313 312 return false;
314 313 };
315 314
316 315
317 316 RawCell.prototype.select = function () {
318 317 IPython.Cell.prototype.select.apply(this);
319 318 this.code_mirror.refresh();
320 319 this.code_mirror.focus();
321 320 };
322 321
323 322
324 323 RawCell.prototype.at_top = function () {
325 324 var cursor = this.code_mirror.getCursor();
326 325 if (cursor.line === 0 && cursor.ch === 0) {
327 326 return true;
328 327 } else {
329 328 return false;
330 329 }
331 330 };
332 331
333 332
334 333 RawCell.prototype.at_bottom = function () {
335 334 var cursor = this.code_mirror.getCursor();
336 335 if (cursor.line === (this.code_mirror.lineCount()-1) && cursor.ch === this.code_mirror.getLine(cursor.line).length) {
337 336 return true;
338 337 } else {
339 338 return false;
340 339 }
341 340 };
342 341
343 342
344 343 // HTMLCell
345 344
346 345 var HeadingCell = function () {
347 346 this.placeholder = "Type Heading Here";
348 347 IPython.TextCell.apply(this, arguments);
349 348 this.cell_type = 'heading';
350 349 this.level = 1;
351 350 };
352 351
353 352
354 353 HeadingCell.prototype = new TextCell();
355 354
356 355
357 356 HeadingCell.prototype.fromJSON = function (data) {
358 357 if (data.level != undefined){
359 358 this.level = data.level;
360 359 }
361 360 IPython.TextCell.prototype.fromJSON.apply(this, arguments);
362 361 };
363 362
364 363
365 364 HeadingCell.prototype.toJSON = function () {
366 365 var data = IPython.TextCell.prototype.toJSON.apply(this);
367 366 data.level = this.get_level();
368 367 return data;
369 368 };
370 369
371 370
372 371 HeadingCell.prototype.set_level = function (level) {
373 372 this.level = level;
374 373 if (this.rendered) {
375 374 this.rendered = false;
376 375 this.render();
377 376 };
378 377 };
379 378
380 379
381 380 HeadingCell.prototype.get_level = function () {
382 381 return this.level;
383 382 };
384 383
385 384
386 385 HeadingCell.prototype.set_rendered = function (text) {
387 386 var r = this.element.find("div.text_cell_render");
388 387 r.empty();
389 388 r.append($('<h'+this.level+'/>').html(text));
390 389 };
391 390
392 391
393 392 HeadingCell.prototype.get_rendered = function () {
394 393 var r = this.element.find("div.text_cell_render");
395 394 return r.children().first().html();
396 395 };
397 396
398 397
399 398 HeadingCell.prototype.render = function () {
400 399 if (this.rendered === false) {
401 400 var text = this.get_text();
402 401 if (text === "") { text = this.placeholder; }
403 402 this.set_rendered(text);
404 403 this.typeset();
405 404 this.element.find('div.text_cell_input').hide();
406 405 this.element.find("div.text_cell_render").show();
407 406 this.rendered = true;
408 407 };
409 408 };
410 409
411 410 IPython.TextCell = TextCell;
412 411 IPython.HTMLCell = HTMLCell;
413 412 IPython.MarkdownCell = MarkdownCell;
414 413 IPython.RawCell = RawCell;
415 414 IPython.HeadingCell = HeadingCell;
416 415
417 416
418 417 return IPython;
419 418
420 419 }(IPython));
421 420
@@ -1,226 +1,241 b''
1 1 {% extends page.html %}
2 2 {% block stylesheet %}
3 3
4 4 {% if mathjax_url %}
5 <script type="text/x-mathjax-config">
6 MathJax.Hub.Config({
7 TeX: { equationNumbers: { autoNumber: "AMS", useLabelIds: true } },
8 tex2jax: {
9 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
10 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
11 processEnvironments: true
12 },
13 displayAlign: 'left', // Change this to 'center' to center equations.
14 "HTML-CSS": {
15 styles: {'.MathJax_Display': {"margin": 0}}
16 }
17 });
18 </script>
19
5 20 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
6 21 {% end %}
7 22 <script type="text/javascript">
8 23 // MathJax disabled, set as null to distingish from *missing* MathJax,
9 24 // where it will be undefined, and should prompt a dialog later.
10 25 window.mathjax_url = "{{mathjax_url}}";
11 26 </script>
12 27
13 28 <link rel="stylesheet" href="{{ static_url("codemirror/lib/codemirror.css") }}">
14 29 <link rel="stylesheet" href="{{ static_url("codemirror/theme/ipython.css") }}">
15 30
16 31 <link rel="stylesheet" href="{{ static_url("prettify/prettify.css") }}"/>
17 32
18 33 <link rel="stylesheet" href="{{ static_url("css/notebook.css") }}" type="text/css" />
19 34 <link rel="stylesheet" href="{{ static_url("css/tooltip.css") }}" type="text/css" />
20 35 <link rel="stylesheet" href="{{ static_url("css/renderedhtml.css") }}" type="text/css" />
21 36
22 37 <link rel="stylesheet" href="{{ static_url("css/printnotebook.css") }}" type="text/css" media="print"/>
23 38
24 39 {% end %}
25 40
26 41
27 42 {% block params %}
28 43
29 44 data-project={{project}}
30 45 data-base-project-url={{base_project_url}}
31 46 data-base-kernel-url={{base_kernel_url}}
32 47 data-read-only={{read_only and not logged_in}}
33 48 data-notebook-id={{notebook_id}}
34 49
35 50 {% end %}
36 51
37 52
38 53 {% block header %}
39 54
40 55 <span id="save_widget">
41 56 <span id="notebook_name"></span>
42 57 <span id="save_status"></span>
43 58 </span>
44 59
45 60 {% end %}
46 61
47 62
48 63 {% block site %}
49 64
50 65 <div id="menubar_container">
51 66 <div id="menubar">
52 67 <ul id="menus">
53 68 <li><a href="#">File</a>
54 69 <ul>
55 70 <li id="new_notebook"><a href="#">New</a></li>
56 71 <li id="open_notebook"><a href="#">Open...</a></li>
57 72 <hr/>
58 73 <li id="copy_notebook"><a href="#">Make a Copy...</a></li>
59 74 <li id="rename_notebook"><a href="#">Rename...</a></li>
60 75 <li id="save_notebook"><a href="#">Save</a></li>
61 76 <hr/>
62 77 <li><a href="#">Download as</a>
63 78 <ul>
64 79 <li id="download_ipynb"><a href="#">IPython (.ipynb)</a></li>
65 80 <li id="download_py"><a href="#">Python (.py)</a></li>
66 81 </ul>
67 82 </li>
68 83 <hr/>
69 84 <li id="print_notebook"><a href="/{{notebook_id}}/print" target="_blank">Print View</a></li>
70 85 <hr/>
71 86 <li id="kill_and_exit"><a href="#" >Close and halt</a></li>
72 87 </ul>
73 88 </li>
74 89 <li><a href="#">Edit</a>
75 90 <ul>
76 91 <li id="cut_cell"><a href="#">Cut Cell</a></li>
77 92 <li id="copy_cell"><a href="#">Copy Cell</a></li>
78 93 <li id="paste_cell" class="ui-state-disabled"><a href="#">Paste Cell</a></li>
79 94 <li id="paste_cell_above" class="ui-state-disabled"><a href="#">Paste Cell Above</a></li>
80 95 <li id="paste_cell_below" class="ui-state-disabled"><a href="#">Paste Cell Below</a></li>
81 96 <li id="delete_cell"><a href="#">Delete</a></li>
82 97 <hr/>
83 98 <li id="split_cell"><a href="#">Split Cell</a></li>
84 99 <li id="merge_cell_above"><a href="#">Merge Cell Above</a></li>
85 100 <li id="merge_cell_below"><a href="#">Merge Cell Below</a></li>
86 101 <hr/>
87 102 <li id="move_cell_up"><a href="#">Move Cell Up</a></li>
88 103 <li id="move_cell_down"><a href="#">Move Cell Down</a></li>
89 104 <hr/>
90 105 <li id="select_previous"><a href="#">Select Previous Cell</a></li>
91 106 <li id="select_next"><a href="#">Select Next Cell</a></li>
92 107 </ul>
93 108 </li>
94 109 <li><a href="#">View</a>
95 110 <ul>
96 111 <li id="toggle_header"><a href="#">Toggle Header</a></li>
97 112 <li id="toggle_toolbar"><a href="#">Toggle Toolbar</a></li>
98 113 </ul>
99 114 </li>
100 115 <li><a href="#">Insert</a>
101 116 <ul>
102 117 <li id="insert_cell_above"><a href="#">Insert Cell Above</a></li>
103 118 <li id="insert_cell_below"><a href="#">Insert Cell Below</a></li>
104 119 </ul>
105 120 </li>
106 121 <li><a href="#">Cell</a>
107 122 <ul>
108 123 <li id="run_cell"><a href="#">Run</a></li>
109 124 <li id="run_cell_in_place"><a href="#">Run in Place</a></li>
110 125 <li id="run_all_cells"><a href="#">Run All</a></li>
111 126 <li id="run_all_cells_above"><a href="#">Run All Above</a></li>
112 127 <li id="run_all_cells_below"><a href="#">Run All Below</a></li>
113 128 <hr/>
114 129 <li id="to_code"><a href="#">Code</a></li>
115 130 <li id="to_markdown"><a href="#">Markdown </a></li>
116 131 <li id="to_raw"><a href="#">Raw Text</a></li>
117 132 <li id="to_heading1"><a href="#">Heading 1</a></li>
118 133 <li id="to_heading2"><a href="#">Heading 2</a></li>
119 134 <li id="to_heading3"><a href="#">Heading 3</a></li>
120 135 <li id="to_heading4"><a href="#">Heading 4</a></li>
121 136 <li id="to_heading5"><a href="#">Heading 5</a></li>
122 137 <li id="to_heading6"><a href="#">Heading 6</a></li>
123 138 <hr/>
124 139 <li id="toggle_output"><a href="#">Toggle Current Output</a></li>
125 140 <li id="all_outputs"><a href="#">All Output</a>
126 141 <ul>
127 142 <li id="expand_all_output"><a href="#">Expand</a></li>
128 143 <li id="scroll_all_output"><a href="#">Scroll Long</a></li>
129 144 <li id="collapse_all_output"><a href="#">Collapse</a></li>
130 145 <li id="clear_all_output"><a href="#">Clear</a></li>
131 146 </ul>
132 147 </li>
133 148 </ul>
134 149 </li>
135 150 <li><a href="#">Kernel</a>
136 151 <ul>
137 152 <li id="int_kernel"><a href="#">Interrupt</a></li>
138 153 <li id="restart_kernel"><a href="#">Restart</a></li>
139 154 </ul>
140 155 </li>
141 156 <li><a href="#">Help</a>
142 157 <ul>
143 158 <li><a href="http://ipython.org/documentation.html" target="_blank">IPython Help</a></li>
144 159 <li><a href="http://ipython.org/ipython-doc/stable/interactive/htmlnotebook.html" target="_blank">Notebook Help</a></li>
145 160 <li id="keyboard_shortcuts"><a href="#">Keyboard Shortcuts</a></li>
146 161 <hr/>
147 162 <li><a href="http://docs.python.org" target="_blank">Python</a></li>
148 163 <li><a href="http://docs.scipy.org/doc/numpy/reference/" target="_blank">NumPy</a></li>
149 164 <li><a href="http://docs.scipy.org/doc/scipy/reference/" target="_blank">SciPy</a></li>
150 165 <li><a href="http://docs.sympy.org/dev/index.html" target="_blank">SymPy</a></li>
151 166 <li><a href="http://matplotlib.sourceforge.net/" target="_blank">Matplotlib</a></li>
152 167 </ul>
153 168 </li>
154 169 </ul>
155 170
156 171 </div>
157 172 <div id="notification_area">
158 173 </div>
159 174 </div>
160 175
161 176
162 177 <div id="maintoolbar"></div>
163 178
164 179 <div id="main_app">
165 180
166 181 <div id="notebook_panel">
167 182 <div id="notebook"></div>
168 183 <div id="pager_splitter"></div>
169 184 <div id="pager_container">
170 185 <div id='pager_button_area'>
171 186 </div>
172 187 <div id="pager"></div>
173 188 </div>
174 189 </div>
175 190
176 191 </div>
177 192 <div id='tooltip' class='ipython_tooltip ui-corner-all' style='display:none'></div>
178 193
179 194
180 195 {% end %}
181 196
182 197
183 198 {% block script %}
184 199
185 200 <script src="{{ static_url("codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
186 201 <script src="{{ static_url("codemirror/lib/util/loadmode.js") }}" charset="utf-8"></script>
187 202 <script src="{{ static_url("codemirror/lib/util/multiplex.js") }}" charset="utf-8"></script>
188 203 <script src="{{ static_url("codemirror/mode/python/python.js") }}" charset="utf-8"></script>
189 204 <script src="{{ static_url("codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script>
190 205 <script src="{{ static_url("codemirror/mode/xml/xml.js") }}" charset="utf-8"></script>
191 206 <script src="{{ static_url("codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script>
192 207 <script src="{{ static_url("codemirror/mode/css/css.js") }}" charset="utf-8"></script>
193 208 <script src="{{ static_url("codemirror/mode/rst/rst.js") }}" charset="utf-8"></script>
194 209 <script src="{{ static_url("codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script>
195 210
196 211 <script src="{{ static_url("pagedown/Markdown.Converter.js") }}" charset="utf-8"></script>
197 212
198 213 <script src="{{ static_url("prettify/prettify.js") }}" charset="utf-8"></script>
199 214 <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script>
200 215
201 216 <script src="{{ static_url("js/events.js") }}" type="text/javascript" charset="utf-8"></script>
202 217 <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script>
203 218 <script src="{{ static_url("js/layoutmanager.js") }}" type="text/javascript" charset="utf-8"></script>
204 219 <script src="{{ static_url("js/mathjaxutils.js") }}" type="text/javascript" charset="utf-8"></script>
205 220 <script src="{{ static_url("js/outputarea.js") }}" type="text/javascript" charset="utf-8"></script>
206 221 <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script>
207 222 <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>
208 223 <script src="{{ static_url("js/completer.js") }}" type="text/javascript" charset="utf-8"></script>
209 224 <script src="{{ static_url("js/textcell.js") }}" type="text/javascript" charset="utf-8"></script>
210 225 <script src="{{ static_url("js/kernel.js") }}" type="text/javascript" charset="utf-8"></script>
211 226 <script src="{{ static_url("js/savewidget.js") }}" type="text/javascript" charset="utf-8"></script>
212 227 <script src="{{ static_url("js/quickhelp.js") }}" type="text/javascript" charset="utf-8"></script>
213 228 <script src="{{ static_url("js/pager.js") }}" type="text/javascript" charset="utf-8"></script>
214 229 <script src="{{ static_url("js/menubar.js") }}" type="text/javascript" charset="utf-8"></script>
215 230 <script src="{{ static_url("js/toolbar.js") }}" type="text/javascript" charset="utf-8"></script>
216 231 <script src="{{ static_url("js/maintoolbar.js") }}" type="text/javascript" charset="utf-8"></script>
217 232 <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
218 233 <script src="{{ static_url("js/notificationwidget.js") }}" type="text/javascript" charset="utf-8"></script>
219 234 <script src="{{ static_url("js/notificationarea.js") }}" type="text/javascript" charset="utf-8"></script>
220 235 <script src="{{ static_url("js/tooltip.js") }}" type="text/javascript" charset="utf-8"></script>
221 236 <script src="{{ static_url("js/config.js") }}" type="text/javascript" charset="utf-8"></script>
222 237 <script src="{{ static_url("js/notebookmain.js") }}" type="text/javascript" charset="utf-8"></script>
223 238
224 239 <script src="{{ static_url("js/contexthint.js") }}" charset="utf-8"></script>
225 240
226 241 {% end %}
@@ -1,81 +1,96 b''
1 1 {% extends page.html %}
2 2
3 3 {% block stylesheet %}
4 4
5 5 {% if mathjax_url %}
6 <script type="text/x-mathjax-config">
7 MathJax.Hub.Config({
8 TeX: { equationNumbers: { autoNumber: "AMS", useLabelIds: true } },
9 tex2jax: {
10 inlineMath: [ ['$','$'], ["\\(","\\)"] ],
11 displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
12 processEnvironments: true
13 },
14 displayAlign: 'left', // Change this to 'center' to center equations.
15 "HTML-CSS": {
16 styles: {'.MathJax_Display': {"margin": 0}}
17 }
18 });
19 </script>
20
6 21 <script type="text/javascript" src="{{mathjax_url}}?config=TeX-AMS_HTML" charset="utf-8"></script>
7 22 {% end %}
8 23 <script type="text/javascript">
9 24 // MathJax disabled, set as null to distingish from *missing* MathJax,
10 25 // where it will be undefined, and should prompt a dialog later.
11 26 window.mathjax_url = "{{mathjax_url}}";
12 27 </script>
13 28
14 29 <link rel="stylesheet" href="{{ static_url("codemirror/lib/codemirror.css") }}">
15 30 <link rel="stylesheet" href="{{ static_url("codemirror/theme/ipython.css") }}">
16 31
17 32 <link rel="stylesheet" href="{{ static_url("prettify/prettify.css") }}"/>
18 33
19 34 <link rel="stylesheet" href="{{ static_url("css/notebook.css") }}" type="text/css" />
20 35 <link rel="stylesheet" href="{{ static_url("css/printnotebook.css") }}" type="text/css" />
21 36 <link rel="stylesheet" href="{{ static_url("css/renderedhtml.css") }}" type="text/css" />
22 37
23 38 {% end %}
24 39
25 40
26 41 {% block params %}
27 42
28 43 data-project={{project}}
29 44 data-base-project-url={{base_project_url}}
30 45 data-base-kernel-url={{base_kernel_url}}
31 46 data-read-only={{read_only and not logged_in}}
32 47 data-notebook-id={{notebook_id}}
33 48
34 49 {% end %}
35 50
36 51
37 52 {% block header %}
38 53 {% end %}
39 54
40 55
41 56 {% block site %}
42 57
43 58 <div id="main_app">
44 59
45 60 <div id="notebook_panel">
46 61 <div id="notebook"></div>
47 62 </div>
48 63
49 64 </div>
50 65
51 66 {% end %}
52 67
53 68
54 69 {% block script %}
55 70
56 71 <script src="{{ static_url("codemirror/lib/codemirror.js") }}" charset="utf-8"></script>
57 72 <script src="{{ static_url("codemirror/mode/python/python.js") }}" charset="utf-8"></script>
58 73 <script src="{{ static_url("codemirror/mode/htmlmixed/htmlmixed.js") }}" charset="utf-8"></script>
59 74 <script src="{{ static_url("codemirror/mode/xml/xml.js") }}" charset="utf-8"></script>
60 75 <script src="{{ static_url("codemirror/mode/javascript/javascript.js") }}" charset="utf-8"></script>
61 76 <script src="{{ static_url("codemirror/mode/css/css.js") }}" charset="utf-8"></script>
62 77 <script src="{{ static_url("codemirror/mode/rst/rst.js") }}" charset="utf-8"></script>
63 78 <script src="{{ static_url("codemirror/mode/markdown/markdown.js") }}" charset="utf-8"></script>
64 79
65 80 <script src="{{ static_url("pagedown/Markdown.Converter.js") }}" charset="utf-8"></script>
66 81
67 82 <script src="{{ static_url("prettify/prettify.js") }}" charset="utf-8"></script>
68 83 <script src="{{ static_url("dateformat/date.format.js") }}" charset="utf-8"></script>
69 84
70 85 <script src="{{ static_url("js/events.js") }}" type="text/javascript" charset="utf-8"></script>
71 86 <script src="{{ static_url("js/utils.js") }}" type="text/javascript" charset="utf-8"></script>
72 87 <script src="{{ static_url("js/mathjaxutils.js") }}" type="text/javascript" charset="utf-8"></script>
73 88 <script src="{{ static_url("js/outputarea.js") }}" type="text/javascript" charset="utf-8"></script>
74 89 <script src="{{ static_url("js/cell.js") }}" type="text/javascript" charset="utf-8"></script>
75 90 <script src="{{ static_url("js/codecell.js") }}" type="text/javascript" charset="utf-8"></script>
76 91 <script src="{{ static_url("js/textcell.js") }}" type="text/javascript" charset="utf-8"></script>
77 92 <script src="{{ static_url("js/kernel.js") }}" type="text/javascript" charset="utf-8"></script>
78 93 <script src="{{ static_url("js/notebook.js") }}" type="text/javascript" charset="utf-8"></script>
79 94 <script src="{{ static_url("js/printnotebookmain.js") }}" type="text/javascript" charset="utf-8"></script>
80 95
81 96 {% end %}
@@ -1,347 +1,339 b''
1 1 {
2 2 "metadata": {
3 3 "name": "Typesetting Math Using MathJax"
4 4 },
5 5 "nbformat": 3,
6 6 "nbformat_minor": 0,
7 7 "worksheets": [
8 8 {
9 9 "cells": [
10 10 {
11 11 "cell_type": "markdown",
12 12 "metadata": {},
13 13 "source": [
14 14 "The Markdown parser included in IPython is MathJax-aware. This means that you can freely mix in mathematical expressions using the [MathJax subset of Tex and LaTeX](http://docs.mathjax.org/en/latest/tex.html#tex-support). [Some examples from the MathJax site](http://www.mathjax.org/demos/tex-samples/) are reproduced below, as well as the Markdown+TeX source."
15 15 ]
16 16 },
17 17 {
18 18 "cell_type": "markdown",
19 19 "metadata": {},
20 20 "source": [
21 21 "# Motivating Examples\n",
22 22 "\n",
23 23 "---\n",
24 24 "\n",
25 25 "## The Lorenz Equations\n",
26 26 "### Source\n",
27 27 "```\\begin{aligned}\n",
28 28 "\\dot{x} & = \\sigma(y-x) \\\\\n",
29 29 "\\dot{y} & = \\rho x - y - xz \\\\\n",
30 30 "\\dot{z} & = -\\beta z + xy\n",
31 31 "\\end{aligned}\n",
32 32 "```\n",
33 33 "### Display\n",
34 34 "\\begin{aligned}\n",
35 35 "\\dot{x} & = \\sigma(y-x) \\\\\n",
36 36 "\\dot{y} & = \\rho x - y - xz \\\\\n",
37 37 "\\dot{z} & = -\\beta z + xy\n",
38 38 "\\end{aligned}"
39 39 ]
40 40 },
41 41 {
42 42 "cell_type": "markdown",
43 43 "metadata": {},
44 44 "source": [
45 45 "## The Cauchy-Schwarz Inequality\n",
46 46 "### Source\n",
47 47 "```\\begin{equation*}\n",
48 48 "\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\n",
49 49 "\\end{equation*}\n",
50 50 "```\n",
51 51 "### Display\n",
52 52 "\\begin{equation*}\n",
53 53 "\\left( \\sum_{k=1}^n a_k b_k \\right)^2 \\leq \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)\n",
54 54 "\\end{equation*}"
55 55 ]
56 56 },
57 57 {
58 58 "cell_type": "markdown",
59 59 "metadata": {},
60 60 "source": [
61 61 "## A Cross Product Formula\n",
62 62 "### Source\n",
63 63 "```\\begin{equation*}\n",
64 64 "\\mathbf{V}_1 \\times \\mathbf{V}_2 = \\begin{vmatrix}\n",
65 65 "\\mathbf{i} & \\mathbf{j} & \\mathbf{k} \\\\\n",
66 66 "\\frac{\\partial X}{\\partial u} & \\frac{\\partial Y}{\\partial u} & 0 \\\\\n",
67 67 "\\frac{\\partial X}{\\partial v} & \\frac{\\partial Y}{\\partial v} & 0\n",
68 68 "\\end{vmatrix} \n",
69 69 "\\end{equation*}\n",
70 70 "```\n",
71 71 "### Display\n",
72 72 "\\begin{equation*}\n",
73 73 "\\mathbf{V}_1 \\times \\mathbf{V}_2 = \\begin{vmatrix}\n",
74 74 "\\mathbf{i} & \\mathbf{j} & \\mathbf{k} \\\\\n",
75 75 "\\frac{\\partial X}{\\partial u} & \\frac{\\partial Y}{\\partial u} & 0 \\\\\n",
76 76 "\\frac{\\partial X}{\\partial v} & \\frac{\\partial Y}{\\partial v} & 0\n",
77 77 "\\end{vmatrix} \n",
78 78 "\\end{equation*}"
79 79 ]
80 80 },
81 81 {
82 82 "cell_type": "markdown",
83 83 "metadata": {},
84 84 "source": [
85 85 "## The probability of getting \\(k\\) heads when flipping \\(n\\) coins is\n",
86 86 "### Source\n",
87 87 "```\\begin{equation*}\n",
88 88 "P(E) = {n \\choose k} p^k (1-p)^{ n-k} \n",
89 89 "\\end{equation*}\n",
90 90 "```\n",
91 91 "### Display\n",
92 92 "\\begin{equation*}\n",
93 93 "P(E) = {n \\choose k} p^k (1-p)^{ n-k} \n",
94 94 "\\end{equation*}"
95 95 ]
96 96 },
97 97 {
98 98 "cell_type": "markdown",
99 99 "metadata": {},
100 100 "source": [
101 101 "## An Identity of Ramanujan\n",
102 102 "### Source\n",
103 103 "```\\begin{equation*}\n",
104 104 "\\frac{1}{\\Bigl(\\sqrt{\\phi \\sqrt{5}}-\\phi\\Bigr) e^{\\frac25 \\pi}} =\n",
105 105 "1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}}\n",
106 106 "{1+\\frac{e^{-8\\pi}} {1+\\ldots} } } } \n",
107 107 "\\end{equation*}\n",
108 108 "```\n",
109 109 "### Display\n",
110 110 "\\begin{equation*}\n",
111 111 "\\frac{1}{\\Bigl(\\sqrt{\\phi \\sqrt{5}}-\\phi\\Bigr) e^{\\frac25 \\pi}} =\n",
112 112 "1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}}\n",
113 113 "{1+\\frac{e^{-8\\pi}} {1+\\ldots} } } } \n",
114 114 "\\end{equation*}"
115 115 ]
116 116 },
117 117 {
118 118 "cell_type": "markdown",
119 119 "metadata": {},
120 120 "source": [
121 121 "## A Rogers-Ramanujan Identity\n",
122 122 "### Source\n",
123 123 "```\\begin{equation*}\n",
124 124 "1 + \\frac{q^2}{(1-q)}+\\frac{q^6}{(1-q)(1-q^2)}+\\cdots =\n",
125 125 "\\prod_{j=0}^{\\infty}\\frac{1}{(1-q^{5j+2})(1-q^{5j+3})},\n",
126 126 "\\quad\\quad \\text{for $|q|<1$}. \n",
127 127 "\\end{equation*}\n",
128 128 "```\n",
129 129 "### Display\n",
130 130 "\\begin{equation*}\n",
131 131 "1 + \\frac{q^2}{(1-q)}+\\frac{q^6}{(1-q)(1-q^2)}+\\cdots =\n",
132 132 "\\prod_{j=0}^{\\infty}\\frac{1}{(1-q^{5j+2})(1-q^{5j+3})},\n",
133 133 "\\quad\\quad \\text{for $|q|<1$}. \n",
134 134 "\\end{equation*}"
135 135 ]
136 136 },
137 137 {
138 138 "cell_type": "markdown",
139 139 "metadata": {},
140 140 "source": [
141 141 "## Maxwell's Equations\n",
142 142 "### Source\n",
143 143 "```\\begin{aligned}\n",
144 144 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
145 145 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
146 146 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \n",
147 147 "\\end{aligned}\n",
148 148 "```\n",
149 149 "### Display\n",
150 150 "\\begin{aligned}\n",
151 151 "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\ \\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
152 152 "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
153 153 "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \n",
154 154 "\\end{aligned}"
155 155 ]
156 156 },
157 157 {
158 158 "cell_type": "markdown",
159 159 "metadata": {},
160 160 "source": [
161 161 "# Equation Numbering and References\n",
162 162 "\n",
163 163 "---\n",
164 164 "\n",
165 165 "These equation reference examples are adapted from an [example page in the MathJax documentation](http://cdn.mathjax.org/mathjax/latest/test/sample-eqrefs.html). Note that it's okay to reference equations across cells. Click inside this cell to see the source.\n",
166 166 "\n",
167 167 "## Labeled equations and references\n",
168 168 "\n",
169 169 "Here is a labeled equation:\n",
170 170 "\\begin{equation}\n",
171 171 "x+1\\over\\sqrt{1-x^2}\\label{ref1}\n",
172 172 "\\end{equation}\n",
173 173 "\n",
174 174 "with a reference to ref1: \\ref{ref1},\n",
175 175 "and another numbered one with no label:\n",
176 176 "\\begin{equation}\n",
177 177 "x+1\\over\\sqrt{1-x^2}\n",
178 178 "\\end{equation}"
179 179 ]
180 180 },
181 181 {
182 182 "cell_type": "markdown",
183 183 "metadata": {},
184 184 "source": [
185 185 "## \\nonumber and equation*\n",
186 186 "\n",
187 187 "This one uses \\nonumber:\n",
188 188 "\\begin{equation}\n",
189 189 "x+1\\over\\sqrt{1-x^2}\\nonumber\n",
190 190 "\\end{equation}\n",
191 191 "\n",
192 192 "Here's one with the equation* environment:\n",
193 193 "\\begin{equation*}\n",
194 194 "x+1\\over\\sqrt{1-x^2}\n",
195 195 "\\end{equation*}"
196 196 ]
197 197 },
198 198 {
199 199 "cell_type": "markdown",
200 200 "metadata": {},
201 201 "source": [
202 202 "## Forward references\n",
203 203 "\n",
204 204 "This is a forward reference [\\ref{ref2}] and another \\eqref{ref2} for the \n",
205 205 "following equation:\n",
206 206 "\n",
207 207 "\\begin{equation}\n",
208 208 "x+1\\over\\sqrt{1-x^2}\\label{ref2}\n",
209 209 "\\end{equation}\n",
210 210 "\n",
211 211 "More math:\n",
212 212 "\\begin{equation}\n",
213 213 "x+1\\over\\sqrt{1-x^2}\n",
214 214 "\\end{equation}"
215 215 ]
216 216 },
217 217 {
218 218 "cell_type": "markdown",
219 219 "metadata": {},
220 220 "source": [
221 221 "### References inline and in environments\n",
222 222 "\n",
223 223 "Here is a ref inside math: $\\ref{ref2}+1$ and text after it.\n",
224 224 "\n",
225 225 "\\begin{align} \n",
226 226 "x& = y_1-y_2+y_3-y_5+y_8-\\dots \n",
227 227 "&& \\text{by \\eqref{ref1}}\\\\ \n",
228 228 "& = y'\\circ y^* && \\text{(by \\eqref{ref3})}\\\\ \n",
229 229 "& = y(0) y' && \\text {by Axiom 1.} \n",
230 230 "\\end{align} \n",
231 231 "\n",
232 232 "### Missing references\n",
233 233 "Here's a bad ref [\\ref{ref4}] to a nonexistent label.\n",
234 234 "\n",
235 235 "### Numbering align environments\n",
236 236 "An alignment:\n",
237 237 "\\begin{align}\n",
238 238 "a&=b\\label{ref3}\\cr\n",
239 239 "&=c+d\n",
240 240 "\\end{align}\n",
241 241 "and a starred one:\n",
242 242 "\\begin{align*}\n",
243 243 "a&=b\\cr\n",
244 244 "&=c+d\n",
245 245 "\\end{align*}"
246 246 ]
247 247 },
248 248 {
249 249 "cell_type": "markdown",
250 250 "metadata": {},
251 251 "source": [
252 252 "# Inline Typesetting (Mixing Markdown and TeX)\n",
253 253 "\n",
254 254 "---\n",
255 255 "\n",
256 256 "While display equations look good for a page of samples, the ability to mix math and *formatted* **text** in a paragraph is also important.\n",
257 257 "\n",
258 258 "## Source\n",
259 259 "``` This expression $\\sqrt{3x-1}+(1+x)^2$ is an example of a TeX inline equation in a **[Markdown-formatted](http://daringfireball.net/projects/markdown/)** sentence. \n",
260 260 "```\n",
261 261 "## Display\n",
262 262 "This expression $\\sqrt{3x-1}+(1+x)^2$ is an example of a TeX inline equation in a **[Markdown-formatted](http://daringfireball.net/projects/markdown/)** sentence. "
263 263 ]
264 264 },
265 265 {
266 266 "cell_type": "markdown",
267 267 "metadata": {},
268 268 "source": [
269 269 "# Other Syntax\n",
270 270 "\n",
271 271 "---\n",
272 272 "\n",
273 273 "You will notice in other places on the web that `$$` are needed explicitly to begin and end MathJax typesetting. This is **not** required if you will be using TeX environments, but the IPython notebook will accept this syntax on legacy notebooks. \n",
274 274 "\n",
275 275 "### Source\n",
276 276 "```$$\n",
277 277 "\\begin{array}{c}\n",
278 278 "y_1 \\\\\\\n",
279 279 "y_2 \\mathtt{t}_i \\\\\\\n",
280 280 "z_{3,4}\n",
281 281 "\\end{array}\n",
282 282 "$$\n",
283 283 "```\n",
284 284 "\n",
285 285 "```\n",
286 286 "$$\n",
287 287 "\\begin{array}{c}\n",
288 288 "y_1 \\cr\n",
289 289 "y_2 \\mathtt{t}_i \\cr\n",
290 290 "y_{3}\n",
291 291 "\\end{array}\n",
292 292 "$$\n",
293 293 "```\n",
294 294 "\n",
295 295 "```\n",
296 296 "$$\\begin{eqnarray} \n",
297 297 "x' &=& &x \\sin\\phi &+& z \\cos\\phi \\\\\n",
298 298 "z' &=& - &x \\cos\\phi &+& z \\sin\\phi \\\\\n",
299 299 "\\end{eqnarray}$$\n",
300 300 "```\n",
301 301 "\n",
302 302 "```\n",
303 303 "$$\n",
304 304 "x=4\n",
305 305 "$$\n",
306 306 "```\n",
307 307 "\n",
308 308 "### Display\n",
309 309 "$$\n",
310 310 "\\begin{array}{c}\n",
311 311 "y_1 \\\\\\\n",
312 312 "y_2 \\mathtt{t}_i \\\\\\\n",
313 313 "z_{3,4}\n",
314 314 "\\end{array}\n",
315 315 "$$\n",
316 316 "\n",
317 317 "$$\n",
318 318 "\\begin{array}{c}\n",
319 319 "y_1 \\cr\n",
320 320 "y_2 \\mathtt{t}_i \\cr\n",
321 321 "y_{3}\n",
322 322 "\\end{array}\n",
323 323 "$$\n",
324 324 "\n",
325 325 "$$\\begin{eqnarray} \n",
326 326 "x' &=& &x \\sin\\phi &+& z \\cos\\phi \\\\\n",
327 327 "z' &=& - &x \\cos\\phi &+& z \\sin\\phi \\\\\n",
328 328 "\\end{eqnarray}$$\n",
329 329 "\n",
330 330 "$$\n",
331 331 "x=4\n",
332 332 "$$"
333 333 ]
334 },
335 {
336 "cell_type": "code",
337 "collapsed": false,
338 "input": [],
339 "language": "python",
340 "metadata": {},
341 "outputs": []
342 334 }
343 335 ],
344 336 "metadata": {}
345 337 }
346 338 ]
347 339 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now