##// END OF EJS Templates
remove useless comment
Matthias BUSSONNIER -
Show More
@@ -1,442 +1,441 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'notebook/js/cell',
7 'notebook/js/cell',
8 'base/js/security',
8 'base/js/security',
9 'notebook/js/mathjaxutils',
9 'notebook/js/mathjaxutils',
10 'notebook/js/celltoolbar',
10 'notebook/js/celltoolbar',
11 'components/marked/lib/marked',
11 'components/marked/lib/marked',
12 ], function(IPython, $, cell, security, mathjaxutils, celltoolbar, marked) {
12 ], function(IPython, $, cell, security, mathjaxutils, celltoolbar, marked) {
13 "use strict";
13 "use strict";
14 var Cell = cell.Cell;
14 var Cell = cell.Cell;
15
15
16 var TextCell = function (options) {
16 var TextCell = function (options) {
17 // Constructor
17 // Constructor
18 //
18 //
19 // Construct a new TextCell, codemirror mode is by default 'htmlmixed',
19 // Construct a new TextCell, codemirror mode is by default 'htmlmixed',
20 // and cell type is 'text' cell start as not redered.
20 // and cell type is 'text' cell start as not redered.
21 //
21 //
22 // Parameters:
22 // Parameters:
23 // options: dictionary
23 // options: dictionary
24 // Dictionary of keyword arguments.
24 // Dictionary of keyword arguments.
25 // events: $(Events) instance
25 // events: $(Events) instance
26 // config: dictionary
26 // config: dictionary
27 // keyboard_manager: KeyboardManager instance
27 // keyboard_manager: KeyboardManager instance
28 // notebook: Notebook instance
28 // notebook: Notebook instance
29 options = options || {};
29 options = options || {};
30
30
31 // in all TextCell/Cell subclasses
31 // in all TextCell/Cell subclasses
32 // do not assign most of members here, just pass it down
32 // do not assign most of members here, just pass it down
33 // in the options dict potentially overwriting what you wish.
33 // in the options dict potentially overwriting what you wish.
34 // they will be assigned in the base class.
34 // they will be assigned in the base class.
35 this.notebook = options.notebook;
35 this.notebook = options.notebook;
36 this.events = options.events;
36 this.events = options.events;
37 this.config = options.config;
37 this.config = options.config;
38
38
39 // we cannot put this as a class key as it has handle to "this".
39 // we cannot put this as a class key as it has handle to "this".
40 var cm_overwrite_options = {
40 var cm_overwrite_options = {
41 onKeyEvent: $.proxy(this.handle_keyevent,this)
41 onKeyEvent: $.proxy(this.handle_keyevent,this)
42 };
42 };
43 var config = this.mergeopt(TextCell, this.config, {cm_config:cm_overwrite_options});
43 var config = this.mergeopt(TextCell, this.config, {cm_config:cm_overwrite_options});
44 Cell.apply(this, [{
44 Cell.apply(this, [{
45 config: config,
45 config: config,
46 keyboard_manager: options.keyboard_manager,
46 keyboard_manager: options.keyboard_manager,
47 events: this.events}]);
47 events: this.events}]);
48
48
49 this.cell_type = this.cell_type || 'text';
49 this.cell_type = this.cell_type || 'text';
50 mathjaxutils = mathjaxutils;
50 mathjaxutils = mathjaxutils;
51 this.rendered = false;
51 this.rendered = false;
52 };
52 };
53
53
54 TextCell.prototype = new Cell();
54 TextCell.prototype = new Cell();
55
55
56 TextCell.options_default = {
56 TextCell.options_default = {
57 cm_config : {
57 cm_config : {
58 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
58 extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
59 mode: 'htmlmixed',
59 mode: 'htmlmixed',
60 lineWrapping : true,
60 lineWrapping : true,
61 }
61 }
62 };
62 };
63
63
64
64
65 /**
65 /**
66 * Create the DOM element of the TextCell
66 * Create the DOM element of the TextCell
67 * @method create_element
67 * @method create_element
68 * @private
68 * @private
69 */
69 */
70 TextCell.prototype.create_element = function () {
70 TextCell.prototype.create_element = function () {
71 Cell.prototype.create_element.apply(this, arguments);
71 Cell.prototype.create_element.apply(this, arguments);
72
72
73 var cell = $("<div>").addClass('cell text_cell');
73 var cell = $("<div>").addClass('cell text_cell');
74 cell.attr('tabindex','2');
74 cell.attr('tabindex','2');
75
75
76 var prompt = $('<div/>').addClass('prompt input_prompt');
76 var prompt = $('<div/>').addClass('prompt input_prompt');
77 cell.append(prompt);
77 cell.append(prompt);
78 var inner_cell = $('<div/>').addClass('inner_cell');
78 var inner_cell = $('<div/>').addClass('inner_cell');
79 this.celltoolbar = new celltoolbar.CellToolbar({
79 this.celltoolbar = new celltoolbar.CellToolbar({
80 cell: this,
80 cell: this,
81 notebook: this.notebook});
81 notebook: this.notebook});
82 inner_cell.append(this.celltoolbar.element);
82 inner_cell.append(this.celltoolbar.element);
83 var input_area = $('<div/>').addClass('input_area');
83 var input_area = $('<div/>').addClass('input_area');
84 this.code_mirror = new CodeMirror(input_area.get(0), this.cm_config);
84 this.code_mirror = new CodeMirror(input_area.get(0), this.cm_config);
85 // The tabindex=-1 makes this div focusable.
85 // The tabindex=-1 makes this div focusable.
86 var render_area = $('<div/>').addClass('text_cell_render rendered_html')
86 var render_area = $('<div/>').addClass('text_cell_render rendered_html')
87 .attr('tabindex','-1');
87 .attr('tabindex','-1');
88 inner_cell.append(input_area).append(render_area);
88 inner_cell.append(input_area).append(render_area);
89 cell.append(inner_cell);
89 cell.append(inner_cell);
90 this.element = cell;
90 this.element = cell;
91 };
91 };
92
92
93
93
94 /**
94 /**
95 * Bind the DOM evet to cell actions
95 * Bind the DOM evet to cell actions
96 * Need to be called after TextCell.create_element
96 * Need to be called after TextCell.create_element
97 * @private
97 * @private
98 * @method bind_event
98 * @method bind_event
99 */
99 */
100 TextCell.prototype.bind_events = function () {
100 TextCell.prototype.bind_events = function () {
101 Cell.prototype.bind_events.apply(this);
101 Cell.prototype.bind_events.apply(this);
102 var that = this;
102 var that = this;
103
103
104 this.element.dblclick(function () {
104 this.element.dblclick(function () {
105 if (that.selected === false) {
105 if (that.selected === false) {
106 this.events.trigger('select.Cell', {'cell':that});
106 this.events.trigger('select.Cell', {'cell':that});
107 }
107 }
108 var cont = that.unrender();
108 var cont = that.unrender();
109 if (cont) {
109 if (cont) {
110 that.focus_editor();
110 that.focus_editor();
111 }
111 }
112 });
112 });
113 };
113 };
114
114
115 // Cell level actions
115 // Cell level actions
116
116
117 TextCell.prototype.select = function () {
117 TextCell.prototype.select = function () {
118 var cont = Cell.prototype.select.apply(this);
118 var cont = Cell.prototype.select.apply(this);
119 if (cont) {
119 if (cont) {
120 if (this.mode === 'edit') {
120 if (this.mode === 'edit') {
121 this.code_mirror.refresh();
121 this.code_mirror.refresh();
122 }
122 }
123 }
123 }
124 return cont;
124 return cont;
125 };
125 };
126
126
127 TextCell.prototype.unrender = function () {
127 TextCell.prototype.unrender = function () {
128 if (this.read_only) return;
128 if (this.read_only) return;
129 var cont = Cell.prototype.unrender.apply(this);
129 var cont = Cell.prototype.unrender.apply(this);
130 if (cont) {
130 if (cont) {
131 var text_cell = this.element;
131 var text_cell = this.element;
132 var output = text_cell.find("div.text_cell_render");
132 var output = text_cell.find("div.text_cell_render");
133 if (this.get_text() === this.placeholder) {
133 if (this.get_text() === this.placeholder) {
134 this.set_text('');
134 this.set_text('');
135 }
135 }
136 this.refresh();
136 this.refresh();
137 }
137 }
138 return cont;
138 return cont;
139 };
139 };
140
140
141 TextCell.prototype.execute = function () {
141 TextCell.prototype.execute = function () {
142 this.render();
142 this.render();
143 };
143 };
144
144
145 /**
145 /**
146 * setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
146 * setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
147 * @method get_text
147 * @method get_text
148 * @retrun {string} CodeMirror current text value
148 * @retrun {string} CodeMirror current text value
149 */
149 */
150 TextCell.prototype.get_text = function() {
150 TextCell.prototype.get_text = function() {
151 return this.code_mirror.getValue();
151 return this.code_mirror.getValue();
152 };
152 };
153
153
154 /**
154 /**
155 * @param {string} text - Codemiror text value
155 * @param {string} text - Codemiror text value
156 * @see TextCell#get_text
156 * @see TextCell#get_text
157 * @method set_text
157 * @method set_text
158 * */
158 * */
159 TextCell.prototype.set_text = function(text) {
159 TextCell.prototype.set_text = function(text) {
160 this.code_mirror.setValue(text);
160 this.code_mirror.setValue(text);
161 this.unrender();
161 this.unrender();
162 this.code_mirror.refresh();
162 this.code_mirror.refresh();
163 };
163 };
164
164
165 /**
165 /**
166 * setter :{{#crossLink "TextCell/set_rendered"}}{{/crossLink}}
166 * setter :{{#crossLink "TextCell/set_rendered"}}{{/crossLink}}
167 * @method get_rendered
167 * @method get_rendered
168 * */
168 * */
169 TextCell.prototype.get_rendered = function() {
169 TextCell.prototype.get_rendered = function() {
170 return this.element.find('div.text_cell_render').html();
170 return this.element.find('div.text_cell_render').html();
171 };
171 };
172
172
173 /**
173 /**
174 * @method set_rendered
174 * @method set_rendered
175 */
175 */
176 TextCell.prototype.set_rendered = function(text) {
176 TextCell.prototype.set_rendered = function(text) {
177 this.element.find('div.text_cell_render').html(text);
177 this.element.find('div.text_cell_render').html(text);
178 };
178 };
179
179
180
180
181 /**
181 /**
182 * Create Text cell from JSON
182 * Create Text cell from JSON
183 * @param {json} data - JSON serialized text-cell
183 * @param {json} data - JSON serialized text-cell
184 * @method fromJSON
184 * @method fromJSON
185 */
185 */
186 TextCell.prototype.fromJSON = function (data) {
186 TextCell.prototype.fromJSON = function (data) {
187 Cell.prototype.fromJSON.apply(this, arguments);
187 Cell.prototype.fromJSON.apply(this, arguments);
188 if (data.cell_type === this.cell_type) {
188 if (data.cell_type === this.cell_type) {
189 if (data.source !== undefined) {
189 if (data.source !== undefined) {
190 this.set_text(data.source);
190 this.set_text(data.source);
191 // make this value the starting point, so that we can only undo
191 // make this value the starting point, so that we can only undo
192 // to this state, instead of a blank cell
192 // to this state, instead of a blank cell
193 this.code_mirror.clearHistory();
193 this.code_mirror.clearHistory();
194 // TODO: This HTML needs to be treated as potentially dangerous
194 // TODO: This HTML needs to be treated as potentially dangerous
195 // user input and should be handled before set_rendered.
195 // user input and should be handled before set_rendered.
196 this.set_rendered(data.rendered || '');
196 this.set_rendered(data.rendered || '');
197 this.rendered = false;
197 this.rendered = false;
198 this.render();
198 this.render();
199 }
199 }
200 }
200 }
201 };
201 };
202
202
203 /** Generate JSON from cell
203 /** Generate JSON from cell
204 * @return {object} cell data serialised to json
204 * @return {object} cell data serialised to json
205 */
205 */
206 TextCell.prototype.toJSON = function () {
206 TextCell.prototype.toJSON = function () {
207 var data = Cell.prototype.toJSON.apply(this);
207 var data = Cell.prototype.toJSON.apply(this);
208 data.source = this.get_text();
208 data.source = this.get_text();
209 if (data.source == this.placeholder) {
209 if (data.source == this.placeholder) {
210 data.source = "";
210 data.source = "";
211 }
211 }
212 return data;
212 return data;
213 };
213 };
214
214
215
215
216 var MarkdownCell = function (options) {
216 var MarkdownCell = function (options) {
217 // Constructor
217 // Constructor
218 //
218 //
219 // Parameters:
219 // Parameters:
220 // options: dictionary
220 // options: dictionary
221 // Dictionary of keyword arguments.
221 // Dictionary of keyword arguments.
222 // events: $(Events) instance
222 // events: $(Events) instance
223 // config: dictionary
223 // config: dictionary
224 // keyboard_manager: KeyboardManager instance
224 // keyboard_manager: KeyboardManager instance
225 // notebook: Notebook instance
225 // notebook: Notebook instance
226 options = options || {};
226 options = options || {};
227 var config = this.mergeopt(MarkdownCell, options.config);
227 var config = this.mergeopt(MarkdownCell, options.config);
228 TextCell.apply(this, [$.extend({}, options, {config: config})]);
228 TextCell.apply(this, [$.extend({}, options, {config: config})]);
229
229
230 this.cell_type = 'markdown';
230 this.cell_type = 'markdown';
231 };
231 };
232
232
233 MarkdownCell.options_default = {
233 MarkdownCell.options_default = {
234 cm_config: {
234 cm_config: {
235 mode: 'ipythongfm'
235 mode: 'ipythongfm'
236 },
236 },
237 placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
237 placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
238 };
238 };
239
239
240 MarkdownCell.prototype = new TextCell();
240 MarkdownCell.prototype = new TextCell();
241
241
242 /**
242 /**
243 * @method render
243 * @method render
244 */
244 */
245 MarkdownCell.prototype.render = function () {
245 MarkdownCell.prototype.render = function () {
246 var cont = TextCell.prototype.render.apply(this);
246 var cont = TextCell.prototype.render.apply(this);
247 if (cont) {
247 if (cont) {
248 var text = this.get_text();
248 var text = this.get_text();
249 var math = null;
249 var math = null;
250 if (text === "") { text = this.placeholder; }
250 if (text === "") { text = this.placeholder; }
251 var text_and_math = mathjaxutils.remove_math(text);
251 var text_and_math = mathjaxutils.remove_math(text);
252 text = text_and_math[0];
252 text = text_and_math[0];
253 math = text_and_math[1];
253 math = text_and_math[1];
254 var html = marked.parser(marked.lexer(text));
254 var html = marked.parser(marked.lexer(text));
255 html = mathjaxutils.replace_math(html, math);
255 html = mathjaxutils.replace_math(html, math);
256 html = security.sanitize_html(html);
256 html = security.sanitize_html(html);
257 html = $($.parseHTML(html));
257 html = $($.parseHTML(html));
258 // links in markdown cells should open in new tabs
258 // links in markdown cells should open in new tabs
259 html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
259 html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
260 this.set_rendered(html);
260 this.set_rendered(html);
261 this.typeset();
261 this.typeset();
262 }
262 }
263 return cont;
263 return cont;
264 };
264 };
265
265
266
266
267 var RawCell = function (options) {
267 var RawCell = function (options) {
268 // Constructor
268 // Constructor
269 //
269 //
270 // Parameters:
270 // Parameters:
271 // options: dictionary
271 // options: dictionary
272 // Dictionary of keyword arguments.
272 // Dictionary of keyword arguments.
273 // events: $(Events) instance
273 // events: $(Events) instance
274 // config: dictionary
274 // config: dictionary
275 // keyboard_manager: KeyboardManager instance
275 // keyboard_manager: KeyboardManager instance
276 // notebook: Notebook instance
276 // notebook: Notebook instance
277 options = options || {};
277 options = options || {};
278 var config = this.mergeopt(RawCell, options.config);
278 var config = this.mergeopt(RawCell, options.config);
279 TextCell.apply(this, [$.extend({}, options, {config: config})]);
279 TextCell.apply(this, [$.extend({}, options, {config: config})]);
280
280
281 // RawCell should always hide its rendered div
282 this.cell_type = 'raw';
281 this.cell_type = 'raw';
283 };
282 };
284
283
285 RawCell.options_default = {
284 RawCell.options_default = {
286 placeholder : "Write raw LaTeX or other formats here, for use with nbconvert. " +
285 placeholder : "Write raw LaTeX or other formats here, for use with nbconvert. " +
287 "It will not be rendered in the notebook. " +
286 "It will not be rendered in the notebook. " +
288 "When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
287 "When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
289 };
288 };
290
289
291 RawCell.prototype = new TextCell();
290 RawCell.prototype = new TextCell();
292
291
293 /** @method bind_events **/
292 /** @method bind_events **/
294 RawCell.prototype.bind_events = function () {
293 RawCell.prototype.bind_events = function () {
295 TextCell.prototype.bind_events.apply(this);
294 TextCell.prototype.bind_events.apply(this);
296 var that = this;
295 var that = this;
297 this.element.focusout(function() {
296 this.element.focusout(function() {
298 that.auto_highlight();
297 that.auto_highlight();
299 that.render();
298 that.render();
300 });
299 });
301
300
302 this.code_mirror.on('focus', function() { that.unrender(); });
301 this.code_mirror.on('focus', function() { that.unrender(); });
303 };
302 };
304
303
305 /**
304 /**
306 * Trigger autodetection of highlight scheme for current cell
305 * Trigger autodetection of highlight scheme for current cell
307 * @method auto_highlight
306 * @method auto_highlight
308 */
307 */
309 RawCell.prototype.auto_highlight = function () {
308 RawCell.prototype.auto_highlight = function () {
310 this._auto_highlight(this.config.raw_cell_highlight);
309 this._auto_highlight(this.config.raw_cell_highlight);
311 };
310 };
312
311
313 /** @method render **/
312 /** @method render **/
314 RawCell.prototype.render = function () {
313 RawCell.prototype.render = function () {
315 var cont = TextCell.prototype.render.apply(this);
314 var cont = TextCell.prototype.render.apply(this);
316 if (cont){
315 if (cont){
317 var text = this.get_text();
316 var text = this.get_text();
318 if (text === "") { text = this.placeholder; }
317 if (text === "") { text = this.placeholder; }
319 this.set_text(text);
318 this.set_text(text);
320 this.element.removeClass('rendered');
319 this.element.removeClass('rendered');
321 }
320 }
322 return cont;
321 return cont;
323 };
322 };
324
323
325
324
326 var HeadingCell = function (options) {
325 var HeadingCell = function (options) {
327 // Constructor
326 // Constructor
328 //
327 //
329 // Parameters:
328 // Parameters:
330 // options: dictionary
329 // options: dictionary
331 // Dictionary of keyword arguments.
330 // Dictionary of keyword arguments.
332 // events: $(Events) instance
331 // events: $(Events) instance
333 // config: dictionary
332 // config: dictionary
334 // keyboard_manager: KeyboardManager instance
333 // keyboard_manager: KeyboardManager instance
335 // notebook: Notebook instance
334 // notebook: Notebook instance
336 options = options || {};
335 options = options || {};
337 var config = this.mergeopt(HeadingCell, options.config);
336 var config = this.mergeopt(HeadingCell, options.config);
338 TextCell.apply(this, [$.extend({}, options, {config: config})]);
337 TextCell.apply(this, [$.extend({}, options, {config: config})]);
339
338
340 this.level = 1;
339 this.level = 1;
341 this.cell_type = 'heading';
340 this.cell_type = 'heading';
342 };
341 };
343
342
344 HeadingCell.options_default = {
343 HeadingCell.options_default = {
345 cm_config: {
344 cm_config: {
346 theme: 'heading-1'
345 theme: 'heading-1'
347 },
346 },
348 placeholder: "Type Heading Here"
347 placeholder: "Type Heading Here"
349 };
348 };
350
349
351 HeadingCell.prototype = new TextCell();
350 HeadingCell.prototype = new TextCell();
352
351
353 /** @method fromJSON */
352 /** @method fromJSON */
354 HeadingCell.prototype.fromJSON = function (data) {
353 HeadingCell.prototype.fromJSON = function (data) {
355 if (data.level !== undefined){
354 if (data.level !== undefined){
356 this.level = data.level;
355 this.level = data.level;
357 }
356 }
358 TextCell.prototype.fromJSON.apply(this, arguments);
357 TextCell.prototype.fromJSON.apply(this, arguments);
359 this.code_mirror.setOption("theme", "heading-"+this.level);
358 this.code_mirror.setOption("theme", "heading-"+this.level);
360 };
359 };
361
360
362
361
363 /** @method toJSON */
362 /** @method toJSON */
364 HeadingCell.prototype.toJSON = function () {
363 HeadingCell.prototype.toJSON = function () {
365 var data = TextCell.prototype.toJSON.apply(this);
364 var data = TextCell.prototype.toJSON.apply(this);
366 data.level = this.get_level();
365 data.level = this.get_level();
367 return data;
366 return data;
368 };
367 };
369
368
370 /**
369 /**
371 * Change heading level of cell, and re-render
370 * Change heading level of cell, and re-render
372 * @method set_level
371 * @method set_level
373 */
372 */
374 HeadingCell.prototype.set_level = function (level) {
373 HeadingCell.prototype.set_level = function (level) {
375 this.level = level;
374 this.level = level;
376 this.code_mirror.setOption("theme", "heading-"+level);
375 this.code_mirror.setOption("theme", "heading-"+level);
377
376
378 if (this.rendered) {
377 if (this.rendered) {
379 this.rendered = false;
378 this.rendered = false;
380 this.render();
379 this.render();
381 }
380 }
382 };
381 };
383
382
384 /** The depth of header cell, based on html (h1 to h6)
383 /** The depth of header cell, based on html (h1 to h6)
385 * @method get_level
384 * @method get_level
386 * @return {integer} level - for 1 to 6
385 * @return {integer} level - for 1 to 6
387 */
386 */
388 HeadingCell.prototype.get_level = function () {
387 HeadingCell.prototype.get_level = function () {
389 return this.level;
388 return this.level;
390 };
389 };
391
390
392
391
393 HeadingCell.prototype.get_rendered = function () {
392 HeadingCell.prototype.get_rendered = function () {
394 var r = this.element.find("div.text_cell_render");
393 var r = this.element.find("div.text_cell_render");
395 return r.children().first().html();
394 return r.children().first().html();
396 };
395 };
397
396
398 HeadingCell.prototype.render = function () {
397 HeadingCell.prototype.render = function () {
399 var cont = TextCell.prototype.render.apply(this);
398 var cont = TextCell.prototype.render.apply(this);
400 if (cont) {
399 if (cont) {
401 var text = this.get_text();
400 var text = this.get_text();
402 var math = null;
401 var math = null;
403 // Markdown headings must be a single line
402 // Markdown headings must be a single line
404 text = text.replace(/\n/g, ' ');
403 text = text.replace(/\n/g, ' ');
405 if (text === "") { text = this.placeholder; }
404 if (text === "") { text = this.placeholder; }
406 text = new Array(this.level + 1).join("#") + " " + text;
405 text = new Array(this.level + 1).join("#") + " " + text;
407 var text_and_math = mathjaxutils.remove_math(text);
406 var text_and_math = mathjaxutils.remove_math(text);
408 text = text_and_math[0];
407 text = text_and_math[0];
409 math = text_and_math[1];
408 math = text_and_math[1];
410 var html = marked.parser(marked.lexer(text));
409 var html = marked.parser(marked.lexer(text));
411 html = mathjaxutils.replace_math(html, math);
410 html = mathjaxutils.replace_math(html, math);
412 html = security.sanitize_html(html);
411 html = security.sanitize_html(html);
413 var h = $($.parseHTML(html));
412 var h = $($.parseHTML(html));
414 // add id and linkback anchor
413 // add id and linkback anchor
415 var hash = h.text().replace(/ /g, '-');
414 var hash = h.text().replace(/ /g, '-');
416 h.attr('id', hash);
415 h.attr('id', hash);
417 h.append(
416 h.append(
418 $('<a/>')
417 $('<a/>')
419 .addClass('anchor-link')
418 .addClass('anchor-link')
420 .attr('href', '#' + hash)
419 .attr('href', '#' + hash)
421 .text('¶')
420 .text('¶')
422 );
421 );
423 this.set_rendered(h);
422 this.set_rendered(h);
424 this.typeset();
423 this.typeset();
425 }
424 }
426 return cont;
425 return cont;
427 };
426 };
428
427
429 // Backwards compatability.
428 // Backwards compatability.
430 IPython.TextCell = TextCell;
429 IPython.TextCell = TextCell;
431 IPython.MarkdownCell = MarkdownCell;
430 IPython.MarkdownCell = MarkdownCell;
432 IPython.RawCell = RawCell;
431 IPython.RawCell = RawCell;
433 IPython.HeadingCell = HeadingCell;
432 IPython.HeadingCell = HeadingCell;
434
433
435 var textcell = {
434 var textcell = {
436 'TextCell': TextCell,
435 'TextCell': TextCell,
437 'MarkdownCell': MarkdownCell,
436 'MarkdownCell': MarkdownCell,
438 'RawCell': RawCell,
437 'RawCell': RawCell,
439 'HeadingCell': HeadingCell,
438 'HeadingCell': HeadingCell,
440 };
439 };
441 return textcell;
440 return textcell;
442 });
441 });
General Comments 0
You need to be logged in to leave comments. Login now