Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50654 views
1
// Copyright (c) IPython Development Team.
2
// Distributed under the terms of the Modified BSD License.
3
4
define([
5
'base/js/namespace',
6
'base/js/utils',
7
'jquery',
8
'notebook/js/cell',
9
'base/js/security',
10
'services/config',
11
'notebook/js/mathjaxutils',
12
'notebook/js/celltoolbar',
13
'components/marked/lib/marked',
14
'codemirror/lib/codemirror',
15
'codemirror/mode/gfm/gfm',
16
'notebook/js/codemirror-ipythongfm'
17
], function(IPython,
18
utils,
19
$,
20
cell,
21
security,
22
configmod,
23
mathjaxutils,
24
celltoolbar,
25
marked,
26
CodeMirror,
27
gfm,
28
ipgfm
29
) {
30
"use strict";
31
var Cell = cell.Cell;
32
33
var TextCell = function (options) {
34
/**
35
* Constructor
36
*
37
* Construct a new TextCell, codemirror mode is by default 'htmlmixed',
38
* and cell type is 'text' cell start as not redered.
39
*
40
* Parameters:
41
* options: dictionary
42
* Dictionary of keyword arguments.
43
* events: $(Events) instance
44
* config: dictionary
45
* keyboard_manager: KeyboardManager instance
46
* notebook: Notebook instance
47
*/
48
options = options || {};
49
50
// in all TextCell/Cell subclasses
51
// do not assign most of members here, just pass it down
52
// in the options dict potentially overwriting what you wish.
53
// they will be assigned in the base class.
54
this.notebook = options.notebook;
55
this.events = options.events;
56
this.config = options.config;
57
58
// we cannot put this as a class key as it has handle to "this".
59
var config = utils.mergeopt(TextCell, this.config);
60
Cell.apply(this, [{
61
config: config,
62
keyboard_manager: options.keyboard_manager,
63
events: this.events}]);
64
65
this.cell_type = this.cell_type || 'text';
66
mathjaxutils = mathjaxutils;
67
this.rendered = false;
68
};
69
70
TextCell.prototype = Object.create(Cell.prototype);
71
72
TextCell.options_default = {
73
cm_config : {
74
extraKeys: {"Tab": "indentMore","Shift-Tab" : "indentLess"},
75
mode: 'htmlmixed',
76
lineWrapping : true,
77
}
78
};
79
80
81
/**
82
* Create the DOM element of the TextCell
83
* @method create_element
84
* @private
85
*/
86
TextCell.prototype.create_element = function () {
87
Cell.prototype.create_element.apply(this, arguments);
88
var that = this;
89
90
var cell = $("<div>").addClass('cell text_cell');
91
cell.attr('tabindex','2');
92
93
var prompt = $('<div/>').addClass('prompt input_prompt');
94
cell.append(prompt);
95
var inner_cell = $('<div/>').addClass('inner_cell');
96
this.celltoolbar = new celltoolbar.CellToolbar({
97
cell: this,
98
notebook: this.notebook});
99
inner_cell.append(this.celltoolbar.element);
100
var input_area = $('<div/>').addClass('input_area');
101
this.code_mirror = new CodeMirror(input_area.get(0), this.cm_config);
102
// In case of bugs that put the keyboard manager into an inconsistent state,
103
// ensure KM is enabled when CodeMirror is focused:
104
this.code_mirror.on('focus', function () {
105
if (that.keyboard_manager) {
106
that.keyboard_manager.enable();
107
}
108
});
109
this.code_mirror.on('keydown', $.proxy(this.handle_keyevent,this))
110
// The tabindex=-1 makes this div focusable.
111
var render_area = $('<div/>').addClass('text_cell_render rendered_html')
112
.attr('tabindex','-1');
113
inner_cell.append(input_area).append(render_area);
114
cell.append(inner_cell);
115
this.element = cell;
116
};
117
118
119
// Cell level actions
120
121
TextCell.prototype.select = function () {
122
var cont = Cell.prototype.select.apply(this);
123
if (cont) {
124
if (this.mode === 'edit') {
125
this.code_mirror.refresh();
126
}
127
}
128
return cont;
129
};
130
131
TextCell.prototype.unrender = function () {
132
var cont = Cell.prototype.unrender.apply(this);
133
if (cont) {
134
var text_cell = this.element;
135
if (this.get_text() === this.placeholder) {
136
this.set_text('');
137
}
138
this.refresh();
139
}
140
return cont;
141
};
142
143
TextCell.prototype.execute = function () {
144
this.render();
145
};
146
147
/**
148
* setter: {{#crossLink "TextCell/set_text"}}{{/crossLink}}
149
* @method get_text
150
* @retrun {string} CodeMirror current text value
151
*/
152
TextCell.prototype.get_text = function() {
153
return this.code_mirror.getValue();
154
};
155
156
/**
157
* @param {string} text - Codemiror text value
158
* @see TextCell#get_text
159
* @method set_text
160
* */
161
TextCell.prototype.set_text = function(text) {
162
this.code_mirror.setValue(text);
163
this.unrender();
164
this.code_mirror.refresh();
165
};
166
167
/**
168
* setter :{{#crossLink "TextCell/set_rendered"}}{{/crossLink}}
169
* @method get_rendered
170
* */
171
TextCell.prototype.get_rendered = function() {
172
return this.element.find('div.text_cell_render').html();
173
};
174
175
/**
176
* @method set_rendered
177
*/
178
TextCell.prototype.set_rendered = function(text) {
179
this.element.find('div.text_cell_render').html(text);
180
};
181
182
183
/**
184
* Create Text cell from JSON
185
* @param {json} data - JSON serialized text-cell
186
* @method fromJSON
187
*/
188
TextCell.prototype.fromJSON = function (data) {
189
Cell.prototype.fromJSON.apply(this, arguments);
190
if (data.cell_type === this.cell_type) {
191
if (data.source !== undefined) {
192
this.set_text(data.source);
193
// make this value the starting point, so that we can only undo
194
// to this state, instead of a blank cell
195
this.code_mirror.clearHistory();
196
// TODO: This HTML needs to be treated as potentially dangerous
197
// user input and should be handled before set_rendered.
198
this.set_rendered(data.rendered || '');
199
this.rendered = false;
200
this.render();
201
}
202
}
203
};
204
205
/** Generate JSON from cell
206
* @return {object} cell data serialised to json
207
*/
208
TextCell.prototype.toJSON = function () {
209
var data = Cell.prototype.toJSON.apply(this);
210
data.source = this.get_text();
211
if (data.source == this.placeholder) {
212
data.source = "";
213
}
214
return data;
215
};
216
217
218
var MarkdownCell = function (options) {
219
/**
220
* Constructor
221
*
222
* Parameters:
223
* options: dictionary
224
* Dictionary of keyword arguments.
225
* events: $(Events) instance
226
* config: ConfigSection instance
227
* keyboard_manager: KeyboardManager instance
228
* notebook: Notebook instance
229
*/
230
options = options || {};
231
var config = utils.mergeopt(MarkdownCell, {});
232
this.class_config = new configmod.ConfigWithDefaults(options.config,
233
{}, 'MarkdownCell');
234
TextCell.apply(this, [$.extend({}, options, {config: config})]);
235
236
this.cell_type = 'markdown';
237
};
238
239
MarkdownCell.options_default = {
240
cm_config: {
241
mode: 'ipythongfm'
242
},
243
placeholder: "Type *Markdown* and LaTeX: $\\alpha^2$"
244
};
245
246
MarkdownCell.prototype = Object.create(TextCell.prototype);
247
248
MarkdownCell.prototype.set_heading_level = function (level) {
249
/**
250
* make a markdown cell a heading
251
*/
252
level = level || 1;
253
var source = this.get_text();
254
source = source.replace(/^(#*)\s?/,
255
new Array(level + 1).join('#') + ' ');
256
this.set_text(source);
257
this.refresh();
258
if (this.rendered) {
259
this.render();
260
}
261
};
262
263
/**
264
* @method render
265
*/
266
MarkdownCell.prototype.render = function () {
267
var cont = TextCell.prototype.render.apply(this);
268
if (cont) {
269
var that = this;
270
var text = this.get_text();
271
var math = null;
272
if (text === "") { text = this.placeholder; }
273
var text_and_math = mathjaxutils.remove_math(text);
274
text = text_and_math[0];
275
math = text_and_math[1];
276
marked(text, function (err, html) {
277
html = mathjaxutils.replace_math(html, math);
278
html = security.sanitize_html(html);
279
html = $($.parseHTML(html));
280
// add anchors to headings
281
html.find(":header").addBack(":header").each(function (i, h) {
282
h = $(h);
283
var hash = h.text().replace(/ /g, '-');
284
h.attr('id', hash);
285
h.append(
286
$('<a/>')
287
.addClass('anchor-link')
288
.attr('href', '#' + hash)
289
.text('ΒΆ')
290
);
291
});
292
// links in markdown cells should open in new tabs
293
html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
294
that.set_rendered(html);
295
that.typeset();
296
that.events.trigger("rendered.MarkdownCell", {cell: that});
297
});
298
}
299
return cont;
300
};
301
302
303
var RawCell = function (options) {
304
/**
305
* Constructor
306
*
307
* Parameters:
308
* options: dictionary
309
* Dictionary of keyword arguments.
310
* events: $(Events) instance
311
* config: ConfigSection instance
312
* keyboard_manager: KeyboardManager instance
313
* notebook: Notebook instance
314
*/
315
options = options || {};
316
var config = utils.mergeopt(RawCell, {});
317
TextCell.apply(this, [$.extend({}, options, {config: config})]);
318
319
this.class_config = new configmod.ConfigWithDefaults(options.config,
320
RawCell.config_defaults, 'RawCell');
321
this.cell_type = 'raw';
322
};
323
324
RawCell.options_default = {
325
placeholder : "Write raw LaTeX or other formats here, for use with nbconvert. " +
326
"It will not be rendered in the notebook. " +
327
"When passing through nbconvert, a Raw Cell's content is added to the output unmodified."
328
};
329
330
RawCell.config_defaults = {
331
highlight_modes : {
332
'diff' :{'reg':[/^diff/]}
333
},
334
};
335
336
RawCell.prototype = Object.create(TextCell.prototype);
337
338
/** @method bind_events **/
339
RawCell.prototype.bind_events = function () {
340
TextCell.prototype.bind_events.apply(this);
341
var that = this;
342
this.element.focusout(function() {
343
that.auto_highlight();
344
that.render();
345
});
346
347
this.code_mirror.on('focus', function() { that.unrender(); });
348
};
349
350
/** @method render **/
351
RawCell.prototype.render = function () {
352
var cont = TextCell.prototype.render.apply(this);
353
if (cont){
354
var text = this.get_text();
355
if (text === "") { text = this.placeholder; }
356
this.set_text(text);
357
this.element.removeClass('rendered');
358
this.auto_highlight();
359
}
360
return cont;
361
};
362
363
// Backwards compatability.
364
IPython.TextCell = TextCell;
365
IPython.MarkdownCell = MarkdownCell;
366
IPython.RawCell = RawCell;
367
368
var textcell = {
369
TextCell: TextCell,
370
MarkdownCell: MarkdownCell,
371
RawCell: RawCell
372
};
373
return textcell;
374
});
375
376