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