##// END OF EJS Templates
Latexify formulas contained in html text....
Pablo Winant -
Show More
@@ -1,519 +1,519 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2008-2011 The IPython Development Team
2 // Copyright (C) 2008-2011 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // CodeCell
9 // CodeCell
10 //============================================================================
10 //============================================================================
11
11
12 var IPython = (function (IPython) {
12 var IPython = (function (IPython) {
13
13
14 var utils = IPython.utils;
14 var utils = IPython.utils;
15
15
16 var CodeCell = function (notebook) {
16 var CodeCell = function (notebook) {
17 this.code_mirror = null;
17 this.code_mirror = null;
18 this.input_prompt_number = ' ';
18 this.input_prompt_number = ' ';
19 this.is_completing = false;
19 this.is_completing = false;
20 this.completion_cursor = null;
20 this.completion_cursor = null;
21 this.outputs = [];
21 this.outputs = [];
22 this.collapsed = false;
22 this.collapsed = false;
23 IPython.Cell.apply(this, arguments);
23 IPython.Cell.apply(this, arguments);
24 };
24 };
25
25
26
26
27 CodeCell.prototype = new IPython.Cell();
27 CodeCell.prototype = new IPython.Cell();
28
28
29
29
30 CodeCell.prototype.create_element = function () {
30 CodeCell.prototype.create_element = function () {
31 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
31 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
32 cell.attr('tabindex','2');
32 cell.attr('tabindex','2');
33 var input = $('<div></div>').addClass('input hbox');
33 var input = $('<div></div>').addClass('input hbox');
34 input.append($('<div/>').addClass('prompt input_prompt'));
34 input.append($('<div/>').addClass('prompt input_prompt'));
35 var input_area = $('<div/>').addClass('input_area box-flex1');
35 var input_area = $('<div/>').addClass('input_area box-flex1');
36 this.code_mirror = CodeMirror(input_area.get(0), {
36 this.code_mirror = CodeMirror(input_area.get(0), {
37 indentUnit : 4,
37 indentUnit : 4,
38 mode: 'python',
38 mode: 'python',
39 theme: 'ipython',
39 theme: 'ipython',
40 readOnly: this.read_only,
40 readOnly: this.read_only,
41 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
41 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
42 });
42 });
43 input.append(input_area);
43 input.append(input_area);
44 var output = $('<div></div>').addClass('output vbox');
44 var output = $('<div></div>').addClass('output vbox');
45 cell.append(input).append(output);
45 cell.append(input).append(output);
46 this.element = cell;
46 this.element = cell;
47 this.collapse()
47 this.collapse()
48 };
48 };
49
49
50
50
51 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
51 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
52 // This method gets called in CodeMirror's onKeyDown/onKeyPress
52 // This method gets called in CodeMirror's onKeyDown/onKeyPress
53 // handlers and is used to provide custom key handling. Its return
53 // handlers and is used to provide custom key handling. Its return
54 // value is used to determine if CodeMirror should ignore the event:
54 // value is used to determine if CodeMirror should ignore the event:
55 // true = ignore, false = don't ignore.
55 // true = ignore, false = don't ignore.
56 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
56 if (event.keyCode === 13 && (event.shiftKey || event.ctrlKey)) {
57 // Always ignore shift-enter in CodeMirror as we handle it.
57 // Always ignore shift-enter in CodeMirror as we handle it.
58 return true;
58 return true;
59 } else if (event.keyCode === 9 && event.type == 'keydown') {
59 } else if (event.keyCode === 9 && event.type == 'keydown') {
60 // Tab completion.
60 // Tab completion.
61 var cur = editor.getCursor();
61 var cur = editor.getCursor();
62 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
62 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
63 if (pre_cursor === "") {
63 if (pre_cursor === "") {
64 // Don't autocomplete if the part of the line before the cursor
64 // Don't autocomplete if the part of the line before the cursor
65 // is empty. In this case, let CodeMirror handle indentation.
65 // is empty. In this case, let CodeMirror handle indentation.
66 return false;
66 return false;
67 } else {
67 } else {
68 // Autocomplete the current line.
68 // Autocomplete the current line.
69 event.stop();
69 event.stop();
70 var line = editor.getLine(cur.line);
70 var line = editor.getLine(cur.line);
71 this.is_completing = true;
71 this.is_completing = true;
72 this.completion_cursor = cur;
72 this.completion_cursor = cur;
73 IPython.notebook.complete_cell(this, line, cur.ch);
73 IPython.notebook.complete_cell(this, line, cur.ch);
74 return true;
74 return true;
75 }
75 }
76 } else if (event.keyCode === 8 && event.type == 'keydown') {
76 } else if (event.keyCode === 8 && event.type == 'keydown') {
77 // If backspace and the line ends with 4 spaces, remove them.
77 // If backspace and the line ends with 4 spaces, remove them.
78 var cur = editor.getCursor();
78 var cur = editor.getCursor();
79 var line = editor.getLine(cur.line);
79 var line = editor.getLine(cur.line);
80 var ending = line.slice(-4);
80 var ending = line.slice(-4);
81 if (ending === ' ') {
81 if (ending === ' ') {
82 editor.replaceRange('',
82 editor.replaceRange('',
83 {line: cur.line, ch: cur.ch-4},
83 {line: cur.line, ch: cur.ch-4},
84 {line: cur.line, ch: cur.ch}
84 {line: cur.line, ch: cur.ch}
85 );
85 );
86 event.stop();
86 event.stop();
87 return true;
87 return true;
88 } else {
88 } else {
89 return false;
89 return false;
90 };
90 };
91 } else if (event.keyCode === 76 && event.ctrlKey && event.shiftKey
91 } else if (event.keyCode === 76 && event.ctrlKey && event.shiftKey
92 && event.type == 'keydown') {
92 && event.type == 'keydown') {
93 // toggle line numbers with Ctrl-Shift-L
93 // toggle line numbers with Ctrl-Shift-L
94 this.toggle_line_numbers();
94 this.toggle_line_numbers();
95 }
95 }
96 else {
96 else {
97 // keypress/keyup also trigger on TAB press, and we don't want to
97 // keypress/keyup also trigger on TAB press, and we don't want to
98 // use those to disable tab completion.
98 // use those to disable tab completion.
99 if (this.is_completing && event.keyCode !== 9) {
99 if (this.is_completing && event.keyCode !== 9) {
100 var ed_cur = editor.getCursor();
100 var ed_cur = editor.getCursor();
101 var cc_cur = this.completion_cursor;
101 var cc_cur = this.completion_cursor;
102 if (ed_cur.line !== cc_cur.line || ed_cur.ch !== cc_cur.ch) {
102 if (ed_cur.line !== cc_cur.line || ed_cur.ch !== cc_cur.ch) {
103 this.is_completing = false;
103 this.is_completing = false;
104 this.completion_cursor = null;
104 this.completion_cursor = null;
105 };
105 };
106 };
106 };
107 return false;
107 return false;
108 };
108 };
109 };
109 };
110
110
111
111
112 CodeCell.prototype.finish_completing = function (matched_text, matches) {
112 CodeCell.prototype.finish_completing = function (matched_text, matches) {
113 // console.log("Got matches", matched_text, matches);
113 // console.log("Got matches", matched_text, matches);
114 if (!this.is_completing || matches.length === 0) {return;}
114 if (!this.is_completing || matches.length === 0) {return;}
115
115
116 var that = this;
116 var that = this;
117 var cur = this.completion_cursor;
117 var cur = this.completion_cursor;
118
118
119 var insert = function (selected_text) {
119 var insert = function (selected_text) {
120 that.code_mirror.replaceRange(
120 that.code_mirror.replaceRange(
121 selected_text,
121 selected_text,
122 {line: cur.line, ch: (cur.ch-matched_text.length)},
122 {line: cur.line, ch: (cur.ch-matched_text.length)},
123 {line: cur.line, ch: cur.ch}
123 {line: cur.line, ch: cur.ch}
124 );
124 );
125 };
125 };
126
126
127 if (matches.length === 1) {
127 if (matches.length === 1) {
128 insert(matches[0]);
128 insert(matches[0]);
129 setTimeout(function(){that.code_mirror.focus();}, 50);
129 setTimeout(function(){that.code_mirror.focus();}, 50);
130 return;
130 return;
131 };
131 };
132
132
133 var complete = $('<div/>').addClass('completions');
133 var complete = $('<div/>').addClass('completions');
134 var select = $('<select/>').attr('multiple','true');
134 var select = $('<select/>').attr('multiple','true');
135 for (var i=0; i<matches.length; ++i) {
135 for (var i=0; i<matches.length; ++i) {
136 select.append($('<option/>').text(matches[i]));
136 select.append($('<option/>').text(matches[i]));
137 }
137 }
138 select.children().first().attr('selected','true');
138 select.children().first().attr('selected','true');
139 select.attr('size',Math.min(10,matches.length));
139 select.attr('size',Math.min(10,matches.length));
140 var pos = this.code_mirror.cursorCoords();
140 var pos = this.code_mirror.cursorCoords();
141 complete.css('left',pos.x+'px');
141 complete.css('left',pos.x+'px');
142 complete.css('top',pos.yBot+'px');
142 complete.css('top',pos.yBot+'px');
143 complete.append(select);
143 complete.append(select);
144
144
145 $('body').append(complete);
145 $('body').append(complete);
146 var done = false;
146 var done = false;
147
147
148 var close = function () {
148 var close = function () {
149 if (done) return;
149 if (done) return;
150 done = true;
150 done = true;
151 complete.remove();
151 complete.remove();
152 that.is_completing = false;
152 that.is_completing = false;
153 that.completion_cursor = null;
153 that.completion_cursor = null;
154 };
154 };
155
155
156 var pick = function () {
156 var pick = function () {
157 insert(select.val()[0]);
157 insert(select.val()[0]);
158 close();
158 close();
159 setTimeout(function(){that.code_mirror.focus();}, 50);
159 setTimeout(function(){that.code_mirror.focus();}, 50);
160 };
160 };
161
161
162 select.blur(close);
162 select.blur(close);
163 select.keydown(function (event) {
163 select.keydown(function (event) {
164 var code = event.which;
164 var code = event.which;
165 if (code === 13 || code === 32) {
165 if (code === 13 || code === 32) {
166 // Pressing SPACE or ENTER will cause a pick
166 // Pressing SPACE or ENTER will cause a pick
167 event.stopPropagation();
167 event.stopPropagation();
168 event.preventDefault();
168 event.preventDefault();
169 pick();
169 pick();
170 } else if (code === 38 || code === 40) {
170 } else if (code === 38 || code === 40) {
171 // We don't want the document keydown handler to handle UP/DOWN,
171 // We don't want the document keydown handler to handle UP/DOWN,
172 // but we want the default action.
172 // but we want the default action.
173 event.stopPropagation();
173 event.stopPropagation();
174 } else {
174 } else {
175 // All other key presses exit completion.
175 // All other key presses exit completion.
176 event.stopPropagation();
176 event.stopPropagation();
177 event.preventDefault();
177 event.preventDefault();
178 close();
178 close();
179 that.code_mirror.focus();
179 that.code_mirror.focus();
180 }
180 }
181 });
181 });
182 // Double click also causes a pick.
182 // Double click also causes a pick.
183 select.dblclick(pick);
183 select.dblclick(pick);
184 select.focus();
184 select.focus();
185 };
185 };
186
186
187 CodeCell.prototype.toggle_line_numbers = function () {
187 CodeCell.prototype.toggle_line_numbers = function () {
188 if (this.code_mirror.getOption('lineNumbers') == false) {
188 if (this.code_mirror.getOption('lineNumbers') == false) {
189 this.code_mirror.setOption('lineNumbers', true);
189 this.code_mirror.setOption('lineNumbers', true);
190 } else {
190 } else {
191 this.code_mirror.setOption('lineNumbers', false);
191 this.code_mirror.setOption('lineNumbers', false);
192 }
192 }
193 this.code_mirror.refresh()
193 this.code_mirror.refresh()
194 };
194 };
195
195
196 CodeCell.prototype.select = function () {
196 CodeCell.prototype.select = function () {
197 IPython.Cell.prototype.select.apply(this);
197 IPython.Cell.prototype.select.apply(this);
198 // Todo: this dance is needed because as of CodeMirror 2.12, focus is
198 // Todo: this dance is needed because as of CodeMirror 2.12, focus is
199 // not causing the cursor to blink if the editor is empty initially.
199 // not causing the cursor to blink if the editor is empty initially.
200 // While this seems to fix the issue, this should be fixed
200 // While this seems to fix the issue, this should be fixed
201 // in CodeMirror proper.
201 // in CodeMirror proper.
202 var s = this.code_mirror.getValue();
202 var s = this.code_mirror.getValue();
203 this.code_mirror.focus();
203 this.code_mirror.focus();
204 if (s === '') this.code_mirror.setValue('');
204 if (s === '') this.code_mirror.setValue('');
205 };
205 };
206
206
207
207
208 CodeCell.prototype.select_all = function () {
208 CodeCell.prototype.select_all = function () {
209 var start = {line: 0, ch: 0};
209 var start = {line: 0, ch: 0};
210 var nlines = this.code_mirror.lineCount();
210 var nlines = this.code_mirror.lineCount();
211 var last_line = this.code_mirror.getLine(nlines-1);
211 var last_line = this.code_mirror.getLine(nlines-1);
212 var end = {line: nlines-1, ch: last_line.length};
212 var end = {line: nlines-1, ch: last_line.length};
213 this.code_mirror.setSelection(start, end);
213 this.code_mirror.setSelection(start, end);
214 };
214 };
215
215
216
216
217 CodeCell.prototype.append_output = function (json) {
217 CodeCell.prototype.append_output = function (json) {
218 this.expand();
218 this.expand();
219 if (json.output_type === 'pyout') {
219 if (json.output_type === 'pyout') {
220 this.append_pyout(json);
220 this.append_pyout(json);
221 } else if (json.output_type === 'pyerr') {
221 } else if (json.output_type === 'pyerr') {
222 this.append_pyerr(json);
222 this.append_pyerr(json);
223 } else if (json.output_type === 'display_data') {
223 } else if (json.output_type === 'display_data') {
224 this.append_display_data(json);
224 this.append_display_data(json);
225 } else if (json.output_type === 'stream') {
225 } else if (json.output_type === 'stream') {
226 this.append_stream(json);
226 this.append_stream(json);
227 };
227 };
228 this.outputs.push(json);
228 this.outputs.push(json);
229 };
229 };
230
230
231
231
232 CodeCell.prototype.create_output_area = function () {
232 CodeCell.prototype.create_output_area = function () {
233 var oa = $("<div/>").addClass("hbox output_area");
233 var oa = $("<div/>").addClass("hbox output_area");
234 oa.append($('<div/>').addClass('prompt'));
234 oa.append($('<div/>').addClass('prompt'));
235 return oa;
235 return oa;
236 };
236 };
237
237
238
238
239 CodeCell.prototype.append_pyout = function (json) {
239 CodeCell.prototype.append_pyout = function (json) {
240 n = json.prompt_number || ' ';
240 n = json.prompt_number || ' ';
241 var toinsert = this.create_output_area();
241 var toinsert = this.create_output_area();
242 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
242 toinsert.find('div.prompt').addClass('output_prompt').html('Out[' + n + ']:');
243 this.append_mime_type(json, toinsert);
243 this.append_mime_type(json, toinsert);
244 this.element.find('div.output').append(toinsert);
244 this.element.find('div.output').append(toinsert);
245 // If we just output latex, typeset it.
245 // If we just output latex, typeset it.
246 if (json.latex !== undefined) {
246 if ((json.latex !== undefined) || (json.html !== undefined)) {
247 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
247 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
248 };
248 };
249 };
249 };
250
250
251
251
252 CodeCell.prototype.append_pyerr = function (json) {
252 CodeCell.prototype.append_pyerr = function (json) {
253 var tb = json.traceback;
253 var tb = json.traceback;
254 if (tb !== undefined && tb.length > 0) {
254 if (tb !== undefined && tb.length > 0) {
255 var s = '';
255 var s = '';
256 var len = tb.length;
256 var len = tb.length;
257 for (var i=0; i<len; i++) {
257 for (var i=0; i<len; i++) {
258 s = s + tb[i] + '\n';
258 s = s + tb[i] + '\n';
259 }
259 }
260 s = s + '\n';
260 s = s + '\n';
261 var toinsert = this.create_output_area();
261 var toinsert = this.create_output_area();
262 this.append_text(s, toinsert);
262 this.append_text(s, toinsert);
263 this.element.find('div.output').append(toinsert);
263 this.element.find('div.output').append(toinsert);
264 };
264 };
265 };
265 };
266
266
267
267
268 CodeCell.prototype.append_stream = function (json) {
268 CodeCell.prototype.append_stream = function (json) {
269 // temporary fix: if stream undefined (json file written prior to this patch),
269 // temporary fix: if stream undefined (json file written prior to this patch),
270 // default to most likely stdout:
270 // default to most likely stdout:
271 if (json.stream == undefined){
271 if (json.stream == undefined){
272 json.stream = 'stdout';
272 json.stream = 'stdout';
273 }
273 }
274 var subclass = "output_"+json.stream;
274 var subclass = "output_"+json.stream;
275 if (this.outputs.length > 0){
275 if (this.outputs.length > 0){
276 // have at least one output to consider
276 // have at least one output to consider
277 var last = this.outputs[this.outputs.length-1];
277 var last = this.outputs[this.outputs.length-1];
278 if (last.output_type == 'stream' && json.stream == last.stream){
278 if (last.output_type == 'stream' && json.stream == last.stream){
279 // latest output was in the same stream,
279 // latest output was in the same stream,
280 // so append directly into its pre tag
280 // so append directly into its pre tag
281 this.element.find('div.'+subclass).last().find('pre').append(json.text);
281 this.element.find('div.'+subclass).last().find('pre').append(json.text);
282 return;
282 return;
283 }
283 }
284 }
284 }
285
285
286 // If we got here, attach a new div
286 // If we got here, attach a new div
287 var toinsert = this.create_output_area();
287 var toinsert = this.create_output_area();
288 this.append_text(json.text, toinsert, "output_stream "+subclass);
288 this.append_text(json.text, toinsert, "output_stream "+subclass);
289 this.element.find('div.output').append(toinsert);
289 this.element.find('div.output').append(toinsert);
290 };
290 };
291
291
292
292
293 CodeCell.prototype.append_display_data = function (json) {
293 CodeCell.prototype.append_display_data = function (json) {
294 var toinsert = this.create_output_area();
294 var toinsert = this.create_output_area();
295 this.append_mime_type(json, toinsert)
295 this.append_mime_type(json, toinsert)
296 this.element.find('div.output').append(toinsert);
296 this.element.find('div.output').append(toinsert);
297 // If we just output latex, typeset it.
297 // If we just output latex, typeset it.
298 if (json.latex !== undefined) {
298 if ( (json.latex !== undefined) || (json.html !== undefined) ) {
299 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
299 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
300 };
300 };
301 };
301 };
302
302
303
303
304 CodeCell.prototype.append_mime_type = function (json, element) {
304 CodeCell.prototype.append_mime_type = function (json, element) {
305 if (json.html !== undefined) {
305 if (json.html !== undefined) {
306 this.append_html(json.html, element);
306 this.append_html(json.html, element);
307 } else if (json.latex !== undefined) {
307 } else if (json.latex !== undefined) {
308 this.append_latex(json.latex, element);
308 this.append_latex(json.latex, element);
309 } else if (json.svg !== undefined) {
309 } else if (json.svg !== undefined) {
310 this.append_svg(json.svg, element);
310 this.append_svg(json.svg, element);
311 } else if (json.png !== undefined) {
311 } else if (json.png !== undefined) {
312 this.append_png(json.png, element);
312 this.append_png(json.png, element);
313 } else if (json.jpeg !== undefined) {
313 } else if (json.jpeg !== undefined) {
314 this.append_jpeg(json.jpeg, element);
314 this.append_jpeg(json.jpeg, element);
315 } else if (json.text !== undefined) {
315 } else if (json.text !== undefined) {
316 this.append_text(json.text, element);
316 this.append_text(json.text, element);
317 };
317 };
318 };
318 };
319
319
320
320
321 CodeCell.prototype.append_html = function (html, element) {
321 CodeCell.prototype.append_html = function (html, element) {
322 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_html rendered_html");
322 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_html rendered_html");
323 toinsert.append(html);
323 toinsert.append(html);
324 element.append(toinsert);
324 element.append(toinsert);
325 }
325 }
326
326
327
327
328 CodeCell.prototype.append_text = function (data, element, extra_class) {
328 CodeCell.prototype.append_text = function (data, element, extra_class) {
329 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_text");
329 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_text");
330 if (extra_class){
330 if (extra_class){
331 toinsert.addClass(extra_class);
331 toinsert.addClass(extra_class);
332 }
332 }
333 toinsert.append($("<pre/>").html(data));
333 toinsert.append($("<pre/>").html(data));
334 element.append(toinsert);
334 element.append(toinsert);
335 };
335 };
336
336
337
337
338 CodeCell.prototype.append_svg = function (svg, element) {
338 CodeCell.prototype.append_svg = function (svg, element) {
339 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_svg");
339 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_svg");
340 toinsert.append(svg);
340 toinsert.append(svg);
341 element.append(toinsert);
341 element.append(toinsert);
342 };
342 };
343
343
344
344
345 CodeCell.prototype.append_png = function (png, element) {
345 CodeCell.prototype.append_png = function (png, element) {
346 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_png");
346 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_png");
347 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
347 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
348 element.append(toinsert);
348 element.append(toinsert);
349 };
349 };
350
350
351
351
352 CodeCell.prototype.append_jpeg = function (jpeg, element) {
352 CodeCell.prototype.append_jpeg = function (jpeg, element) {
353 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_jpeg");
353 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_jpeg");
354 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
354 toinsert.append($("<img/>").attr('src','data:image/jpeg;base64,'+jpeg));
355 element.append(toinsert);
355 element.append(toinsert);
356 };
356 };
357
357
358
358
359 CodeCell.prototype.append_latex = function (latex, element) {
359 CodeCell.prototype.append_latex = function (latex, element) {
360 // This method cannot do the typesetting because the latex first has to
360 // This method cannot do the typesetting because the latex first has to
361 // be on the page.
361 // be on the page.
362 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_latex");
362 var toinsert = $("<div/>").addClass("box_flex1 output_subarea output_latex");
363 toinsert.append(latex);
363 toinsert.append(latex);
364 element.append(toinsert);
364 element.append(toinsert);
365 }
365 }
366
366
367
367
368 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
368 CodeCell.prototype.clear_output = function (stdout, stderr, other) {
369 var output_div = this.element.find("div.output");
369 var output_div = this.element.find("div.output");
370 if (stdout && stderr && other){
370 if (stdout && stderr && other){
371 // clear all, no need for logic
371 // clear all, no need for logic
372 output_div.html("");
372 output_div.html("");
373 this.outputs = [];
373 this.outputs = [];
374 return;
374 return;
375 }
375 }
376 // remove html output
376 // remove html output
377 // each output_subarea that has an identifying class is in an output_area
377 // each output_subarea that has an identifying class is in an output_area
378 // which is the element to be removed.
378 // which is the element to be removed.
379 if (stdout){
379 if (stdout){
380 output_div.find("div.output_stdout").parent().remove();
380 output_div.find("div.output_stdout").parent().remove();
381 }
381 }
382 if (stderr){
382 if (stderr){
383 output_div.find("div.output_stderr").parent().remove();
383 output_div.find("div.output_stderr").parent().remove();
384 }
384 }
385 if (other){
385 if (other){
386 output_div.find("div.output_subarea").not("div.output_stderr").not("div.output_stdout").parent().remove();
386 output_div.find("div.output_subarea").not("div.output_stderr").not("div.output_stdout").parent().remove();
387 }
387 }
388
388
389 // remove cleared outputs from JSON list:
389 // remove cleared outputs from JSON list:
390 for (var i = this.outputs.length - 1; i >= 0; i--){
390 for (var i = this.outputs.length - 1; i >= 0; i--){
391 var out = this.outputs[i];
391 var out = this.outputs[i];
392 var output_type = out.output_type;
392 var output_type = out.output_type;
393 if (output_type == "display_data" && other){
393 if (output_type == "display_data" && other){
394 this.outputs.splice(i,1);
394 this.outputs.splice(i,1);
395 }else if (output_type == "stream"){
395 }else if (output_type == "stream"){
396 if (stdout && out.stream == "stdout"){
396 if (stdout && out.stream == "stdout"){
397 this.outputs.splice(i,1);
397 this.outputs.splice(i,1);
398 }else if (stderr && out.stream == "stderr"){
398 }else if (stderr && out.stream == "stderr"){
399 this.outputs.splice(i,1);
399 this.outputs.splice(i,1);
400 }
400 }
401 }
401 }
402 }
402 }
403 };
403 };
404
404
405
405
406 CodeCell.prototype.clear_input = function () {
406 CodeCell.prototype.clear_input = function () {
407 this.code_mirror.setValue('');
407 this.code_mirror.setValue('');
408 };
408 };
409
409
410
410
411 CodeCell.prototype.collapse = function () {
411 CodeCell.prototype.collapse = function () {
412 if (!this.collapsed) {
412 if (!this.collapsed) {
413 this.element.find('div.output').hide();
413 this.element.find('div.output').hide();
414 this.collapsed = true;
414 this.collapsed = true;
415 };
415 };
416 };
416 };
417
417
418
418
419 CodeCell.prototype.expand = function () {
419 CodeCell.prototype.expand = function () {
420 if (this.collapsed) {
420 if (this.collapsed) {
421 this.element.find('div.output').show();
421 this.element.find('div.output').show();
422 this.collapsed = false;
422 this.collapsed = false;
423 };
423 };
424 };
424 };
425
425
426
426
427 CodeCell.prototype.toggle_output = function () {
427 CodeCell.prototype.toggle_output = function () {
428 if (this.collapsed) {
428 if (this.collapsed) {
429 this.expand();
429 this.expand();
430 } else {
430 } else {
431 this.collapse();
431 this.collapse();
432 };
432 };
433 };
433 };
434
434
435 CodeCell.prototype.set_input_prompt = function (number) {
435 CodeCell.prototype.set_input_prompt = function (number) {
436 var n = number || ' ';
436 var n = number || ' ';
437 this.input_prompt_number = n
437 this.input_prompt_number = n
438 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
438 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
439 };
439 };
440
440
441
441
442 CodeCell.prototype.get_code = function () {
442 CodeCell.prototype.get_code = function () {
443 return this.code_mirror.getValue();
443 return this.code_mirror.getValue();
444 };
444 };
445
445
446
446
447 CodeCell.prototype.set_code = function (code) {
447 CodeCell.prototype.set_code = function (code) {
448 return this.code_mirror.setValue(code);
448 return this.code_mirror.setValue(code);
449 };
449 };
450
450
451
451
452 CodeCell.prototype.at_top = function () {
452 CodeCell.prototype.at_top = function () {
453 var cursor = this.code_mirror.getCursor();
453 var cursor = this.code_mirror.getCursor();
454 if (cursor.line === 0) {
454 if (cursor.line === 0) {
455 return true;
455 return true;
456 } else {
456 } else {
457 return false;
457 return false;
458 }
458 }
459 };
459 };
460
460
461
461
462 CodeCell.prototype.at_bottom = function () {
462 CodeCell.prototype.at_bottom = function () {
463 var cursor = this.code_mirror.getCursor();
463 var cursor = this.code_mirror.getCursor();
464 if (cursor.line === (this.code_mirror.lineCount()-1)) {
464 if (cursor.line === (this.code_mirror.lineCount()-1)) {
465 return true;
465 return true;
466 } else {
466 } else {
467 return false;
467 return false;
468 }
468 }
469 };
469 };
470
470
471
471
472 CodeCell.prototype.fromJSON = function (data) {
472 CodeCell.prototype.fromJSON = function (data) {
473 console.log('Import from JSON:', data);
473 console.log('Import from JSON:', data);
474 if (data.cell_type === 'code') {
474 if (data.cell_type === 'code') {
475 if (data.input !== undefined) {
475 if (data.input !== undefined) {
476 this.set_code(data.input);
476 this.set_code(data.input);
477 }
477 }
478 if (data.prompt_number !== undefined) {
478 if (data.prompt_number !== undefined) {
479 this.set_input_prompt(data.prompt_number);
479 this.set_input_prompt(data.prompt_number);
480 } else {
480 } else {
481 this.set_input_prompt();
481 this.set_input_prompt();
482 };
482 };
483 var len = data.outputs.length;
483 var len = data.outputs.length;
484 for (var i=0; i<len; i++) {
484 for (var i=0; i<len; i++) {
485 this.append_output(data.outputs[i]);
485 this.append_output(data.outputs[i]);
486 };
486 };
487 if (data.collapsed !== undefined) {
487 if (data.collapsed !== undefined) {
488 if (data.collapsed) {
488 if (data.collapsed) {
489 this.collapse();
489 this.collapse();
490 };
490 };
491 };
491 };
492 };
492 };
493 };
493 };
494
494
495
495
496 CodeCell.prototype.toJSON = function () {
496 CodeCell.prototype.toJSON = function () {
497 var data = {};
497 var data = {};
498 data.input = this.get_code();
498 data.input = this.get_code();
499 data.cell_type = 'code';
499 data.cell_type = 'code';
500 if (this.input_prompt_number !== ' ') {
500 if (this.input_prompt_number !== ' ') {
501 data.prompt_number = this.input_prompt_number
501 data.prompt_number = this.input_prompt_number
502 };
502 };
503 var outputs = [];
503 var outputs = [];
504 var len = this.outputs.length;
504 var len = this.outputs.length;
505 for (var i=0; i<len; i++) {
505 for (var i=0; i<len; i++) {
506 outputs[i] = this.outputs[i];
506 outputs[i] = this.outputs[i];
507 };
507 };
508 data.outputs = outputs;
508 data.outputs = outputs;
509 data.language = 'python';
509 data.language = 'python';
510 data.collapsed = this.collapsed;
510 data.collapsed = this.collapsed;
511 // console.log('Export to JSON:',data);
511 // console.log('Export to JSON:',data);
512 return data;
512 return data;
513 };
513 };
514
514
515
515
516 IPython.CodeCell = CodeCell;
516 IPython.CodeCell = CodeCell;
517
517
518 return IPython;
518 return IPython;
519 }(IPython));
519 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now