Show More
@@ -1,588 +1,588 | |||||
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 | /** |
|
4 | /** | |
5 | * |
|
5 | * | |
6 | * |
|
6 | * | |
7 | * @module cell |
|
7 | * @module cell | |
8 | * @namespace cell |
|
8 | * @namespace cell | |
9 | * @class Cell |
|
9 | * @class Cell | |
10 | */ |
|
10 | */ | |
11 |
|
11 | |||
12 |
|
12 | |||
13 | define([ |
|
13 | define([ | |
14 | 'base/js/namespace', |
|
14 | 'base/js/namespace', | |
15 | 'jquery', |
|
15 | 'jquery', | |
16 | 'base/js/utils', |
|
16 | 'base/js/utils', | |
17 | 'codemirror/lib/codemirror', |
|
17 | 'codemirror/lib/codemirror', | |
18 | 'codemirror/addon/edit/matchbrackets', |
|
18 | 'codemirror/addon/edit/matchbrackets', | |
19 | 'codemirror/addon/edit/closebrackets', |
|
19 | 'codemirror/addon/edit/closebrackets', | |
20 | 'codemirror/addon/comment/comment' |
|
20 | 'codemirror/addon/comment/comment' | |
21 | ], function(IPython, $, utils, CodeMirror, cm_match, cm_closeb, cm_comment) { |
|
21 | ], function(IPython, $, utils, CodeMirror, cm_match, cm_closeb, cm_comment) { | |
22 | // TODO: remove IPython dependency here |
|
22 | // TODO: remove IPython dependency here | |
23 | "use strict"; |
|
23 | "use strict"; | |
24 |
|
24 | |||
25 | var Cell = function (options) { |
|
25 | var Cell = function (options) { | |
26 | /* Constructor |
|
26 | /* Constructor | |
27 | * |
|
27 | * | |
28 | * The Base `Cell` class from which to inherit. |
|
28 | * The Base `Cell` class from which to inherit. | |
29 | * @constructor |
|
29 | * @constructor | |
30 | * @param: |
|
30 | * @param: | |
31 | * options: dictionary |
|
31 | * options: dictionary | |
32 | * Dictionary of keyword arguments. |
|
32 | * Dictionary of keyword arguments. | |
33 |
* events: $(Events) instance |
|
33 | * events: $(Events) instance | |
34 | * config: dictionary |
|
34 | * config: dictionary | |
35 |
* keyboard_manager: KeyboardManager instance |
|
35 | * keyboard_manager: KeyboardManager instance | |
36 | */ |
|
36 | */ | |
37 | options = options || {}; |
|
37 | options = options || {}; | |
38 | this.keyboard_manager = options.keyboard_manager; |
|
38 | this.keyboard_manager = options.keyboard_manager; | |
39 | this.events = options.events; |
|
39 | this.events = options.events; | |
40 | var config = utils.mergeopt(Cell, options.config); |
|
40 | var config = utils.mergeopt(Cell, options.config); | |
41 | // superclass default overwrite our default |
|
41 | // superclass default overwrite our default | |
42 |
|
42 | |||
43 | this.placeholder = config.placeholder || ''; |
|
43 | this.placeholder = config.placeholder || ''; | |
44 | this.read_only = config.cm_config.readOnly; |
|
44 | this.read_only = config.cm_config.readOnly; | |
45 | this.selected = false; |
|
45 | this.selected = false; | |
46 | this.rendered = false; |
|
46 | this.rendered = false; | |
47 | this.mode = 'command'; |
|
47 | this.mode = 'command'; | |
48 | this.metadata = {}; |
|
48 | this.metadata = {}; | |
49 | // load this from metadata later ? |
|
49 | // load this from metadata later ? | |
50 | this.user_highlight = 'auto'; |
|
50 | this.user_highlight = 'auto'; | |
51 | this.cm_config = config.cm_config; |
|
51 | this.cm_config = config.cm_config; | |
52 | this.cell_id = utils.uuid(); |
|
52 | this.cell_id = utils.uuid(); | |
53 | this._options = config; |
|
53 | this._options = config; | |
54 |
|
54 | |||
55 | // For JS VM engines optimization, attributes should be all set (even |
|
55 | // For JS VM engines optimization, attributes should be all set (even | |
56 | // to null) in the constructor, and if possible, if different subclass |
|
56 | // to null) in the constructor, and if possible, if different subclass | |
57 | // have new attributes with same name, they should be created in the |
|
57 | // have new attributes with same name, they should be created in the | |
58 | // same order. Easiest is to create and set to null in parent class. |
|
58 | // same order. Easiest is to create and set to null in parent class. | |
59 |
|
59 | |||
60 | this.element = null; |
|
60 | this.element = null; | |
61 | this.cell_type = this.cell_type || null; |
|
61 | this.cell_type = this.cell_type || null; | |
62 | this.code_mirror = null; |
|
62 | this.code_mirror = null; | |
63 |
|
63 | |||
64 | this.create_element(); |
|
64 | this.create_element(); | |
65 | if (this.element !== null) { |
|
65 | if (this.element !== null) { | |
66 | this.element.data("cell", this); |
|
66 | this.element.data("cell", this); | |
67 | this.bind_events(); |
|
67 | this.bind_events(); | |
68 | this.init_classes(); |
|
68 | this.init_classes(); | |
69 | } |
|
69 | } | |
70 | }; |
|
70 | }; | |
71 |
|
71 | |||
72 | Cell.options_default = { |
|
72 | Cell.options_default = { | |
73 | cm_config : { |
|
73 | cm_config : { | |
74 | indentUnit : 4, |
|
74 | indentUnit : 4, | |
75 | readOnly: false, |
|
75 | readOnly: false, | |
76 | theme: "default", |
|
76 | theme: "default", | |
77 | extraKeys: { |
|
77 | extraKeys: { | |
78 | "Cmd-Right":"goLineRight", |
|
78 | "Cmd-Right":"goLineRight", | |
79 | "End":"goLineRight", |
|
79 | "End":"goLineRight", | |
80 | "Cmd-Left":"goLineLeft" |
|
80 | "Cmd-Left":"goLineLeft" | |
81 | } |
|
81 | } | |
82 | } |
|
82 | } | |
83 | }; |
|
83 | }; | |
84 |
|
84 | |||
85 | // FIXME: Workaround CM Bug #332 (Safari segfault on drag) |
|
85 | // FIXME: Workaround CM Bug #332 (Safari segfault on drag) | |
86 | // by disabling drag/drop altogether on Safari |
|
86 | // by disabling drag/drop altogether on Safari | |
87 | // https://github.com/codemirror/CodeMirror/issues/332 |
|
87 | // https://github.com/codemirror/CodeMirror/issues/332 | |
88 | if (utils.browser[0] == "Safari") { |
|
88 | if (utils.browser[0] == "Safari") { | |
89 | Cell.options_default.cm_config.dragDrop = false; |
|
89 | Cell.options_default.cm_config.dragDrop = false; | |
90 | } |
|
90 | } | |
91 |
|
91 | |||
92 | /** |
|
92 | /** | |
93 | * Empty. Subclasses must implement create_element. |
|
93 | * Empty. Subclasses must implement create_element. | |
94 | * This should contain all the code to create the DOM element in notebook |
|
94 | * This should contain all the code to create the DOM element in notebook | |
95 | * and will be called by Base Class constructor. |
|
95 | * and will be called by Base Class constructor. | |
96 | * @method create_element |
|
96 | * @method create_element | |
97 | */ |
|
97 | */ | |
98 | Cell.prototype.create_element = function () { |
|
98 | Cell.prototype.create_element = function () { | |
99 | }; |
|
99 | }; | |
100 |
|
100 | |||
101 | Cell.prototype.init_classes = function () { |
|
101 | Cell.prototype.init_classes = function () { | |
102 | // Call after this.element exists to initialize the css classes |
|
102 | // Call after this.element exists to initialize the css classes | |
103 | // related to selected, rendered and mode. |
|
103 | // related to selected, rendered and mode. | |
104 | if (this.selected) { |
|
104 | if (this.selected) { | |
105 | this.element.addClass('selected'); |
|
105 | this.element.addClass('selected'); | |
106 | } else { |
|
106 | } else { | |
107 | this.element.addClass('unselected'); |
|
107 | this.element.addClass('unselected'); | |
108 | } |
|
108 | } | |
109 | if (this.rendered) { |
|
109 | if (this.rendered) { | |
110 | this.element.addClass('rendered'); |
|
110 | this.element.addClass('rendered'); | |
111 | } else { |
|
111 | } else { | |
112 | this.element.addClass('unrendered'); |
|
112 | this.element.addClass('unrendered'); | |
113 | } |
|
113 | } | |
114 | if (this.mode === 'edit') { |
|
114 | if (this.mode === 'edit') { | |
115 | this.element.addClass('edit_mode'); |
|
115 | this.element.addClass('edit_mode'); | |
116 | } else { |
|
116 | } else { | |
117 | this.element.addClass('command_mode'); |
|
117 | this.element.addClass('command_mode'); | |
118 | } |
|
118 | } | |
119 | }; |
|
119 | }; | |
120 |
|
120 | |||
121 | /** |
|
121 | /** | |
122 | * Subclasses can implement override bind_events. |
|
122 | * Subclasses can implement override bind_events. | |
123 | * Be carefull to call the parent method when overwriting as it fires event. |
|
123 | * Be carefull to call the parent method when overwriting as it fires event. | |
124 | * this will be triggerd after create_element in constructor. |
|
124 | * this will be triggerd after create_element in constructor. | |
125 | * @method bind_events |
|
125 | * @method bind_events | |
126 | */ |
|
126 | */ | |
127 | Cell.prototype.bind_events = function () { |
|
127 | Cell.prototype.bind_events = function () { | |
128 | var that = this; |
|
128 | var that = this; | |
129 | // We trigger events so that Cell doesn't have to depend on Notebook. |
|
129 | // We trigger events so that Cell doesn't have to depend on Notebook. | |
130 | that.element.click(function (event) { |
|
130 | that.element.click(function (event) { | |
131 | if (!that.selected) { |
|
131 | if (!that.selected) { | |
132 | that.events.trigger('select.Cell', {'cell':that}); |
|
132 | that.events.trigger('select.Cell', {'cell':that}); | |
133 | } |
|
133 | } | |
134 | }); |
|
134 | }); | |
135 | that.element.focusin(function (event) { |
|
135 | that.element.focusin(function (event) { | |
136 | if (!that.selected) { |
|
136 | if (!that.selected) { | |
137 | that.events.trigger('select.Cell', {'cell':that}); |
|
137 | that.events.trigger('select.Cell', {'cell':that}); | |
138 | } |
|
138 | } | |
139 | }); |
|
139 | }); | |
140 | if (this.code_mirror) { |
|
140 | if (this.code_mirror) { | |
141 | this.code_mirror.on("change", function(cm, change) { |
|
141 | this.code_mirror.on("change", function(cm, change) { | |
142 | that.events.trigger("set_dirty.Notebook", {value: true}); |
|
142 | that.events.trigger("set_dirty.Notebook", {value: true}); | |
143 | }); |
|
143 | }); | |
144 | } |
|
144 | } | |
145 | if (this.code_mirror) { |
|
145 | if (this.code_mirror) { | |
146 | this.code_mirror.on('focus', function(cm, change) { |
|
146 | this.code_mirror.on('focus', function(cm, change) { | |
147 | that.events.trigger('edit_mode.Cell', {cell: that}); |
|
147 | that.events.trigger('edit_mode.Cell', {cell: that}); | |
148 | }); |
|
148 | }); | |
149 | } |
|
149 | } | |
150 | if (this.code_mirror) { |
|
150 | if (this.code_mirror) { | |
151 | this.code_mirror.on('blur', function(cm, change) { |
|
151 | this.code_mirror.on('blur', function(cm, change) { | |
152 | that.events.trigger('command_mode.Cell', {cell: that}); |
|
152 | that.events.trigger('command_mode.Cell', {cell: that}); | |
153 | }); |
|
153 | }); | |
154 | } |
|
154 | } | |
155 |
|
155 | |||
156 | this.element.dblclick(function () { |
|
156 | this.element.dblclick(function () { | |
157 | if (that.selected === false) { |
|
157 | if (that.selected === false) { | |
158 | this.events.trigger('select.Cell', {'cell':that}); |
|
158 | this.events.trigger('select.Cell', {'cell':that}); | |
159 | } |
|
159 | } | |
160 | var cont = that.unrender(); |
|
160 | var cont = that.unrender(); | |
161 | if (cont) { |
|
161 | if (cont) { | |
162 | that.focus_editor(); |
|
162 | that.focus_editor(); | |
163 | } |
|
163 | } | |
164 | }); |
|
164 | }); | |
165 | }; |
|
165 | }; | |
166 |
|
166 | |||
167 | /** |
|
167 | /** | |
168 | * This method gets called in CodeMirror's onKeyDown/onKeyPress |
|
168 | * This method gets called in CodeMirror's onKeyDown/onKeyPress | |
169 | * handlers and is used to provide custom key handling. |
|
169 | * handlers and is used to provide custom key handling. | |
170 | * |
|
170 | * | |
171 | * To have custom handling, subclasses should override this method, but still call it |
|
171 | * To have custom handling, subclasses should override this method, but still call it | |
172 | * in order to process the Edit mode keyboard shortcuts. |
|
172 | * in order to process the Edit mode keyboard shortcuts. | |
173 | * |
|
173 | * | |
174 | * @method handle_codemirror_keyevent |
|
174 | * @method handle_codemirror_keyevent | |
175 | * @param {CodeMirror} editor - The codemirror instance bound to the cell |
|
175 | * @param {CodeMirror} editor - The codemirror instance bound to the cell | |
176 | * @param {event} event - key press event which either should or should not be handled by CodeMirror |
|
176 | * @param {event} event - key press event which either should or should not be handled by CodeMirror | |
177 | * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise |
|
177 | * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise | |
178 | */ |
|
178 | */ | |
179 | Cell.prototype.handle_codemirror_keyevent = function (editor, event) { |
|
179 | Cell.prototype.handle_codemirror_keyevent = function (editor, event) { | |
180 | var shortcuts = this.keyboard_manager.edit_shortcuts; |
|
180 | var shortcuts = this.keyboard_manager.edit_shortcuts; | |
181 |
|
181 | |||
182 | var cur = editor.getCursor(); |
|
182 | var cur = editor.getCursor(); | |
183 | if((cur.line !== 0 || cur.ch !==0) && event.keyCode === 38){ |
|
183 | if((cur.line !== 0 || cur.ch !==0) && event.keyCode === 38){ | |
184 | event._ipkmIgnore = true; |
|
184 | event._ipkmIgnore = true; | |
185 | } |
|
185 | } | |
186 |
var nLastLine = editor.lastLine() |
|
186 | var nLastLine = editor.lastLine() | |
187 | if( ( event.keyCode === 40) |
|
187 | if( ( event.keyCode === 40) | |
188 | && (( cur.line !== nLastLine) |
|
188 | && (( cur.line !== nLastLine) | |
189 | || ( cur.ch !== editor.getLineHandle(nLastLine).text.length)) |
|
189 | || ( cur.ch !== editor.getLineHandle(nLastLine).text.length)) | |
190 | ){ |
|
190 | ){ | |
191 | event._ipkmIgnore = true; |
|
191 | event._ipkmIgnore = true; | |
192 | } |
|
192 | } | |
193 | // if this is an edit_shortcuts shortcut, the global keyboard/shortcut |
|
193 | // if this is an edit_shortcuts shortcut, the global keyboard/shortcut | |
194 | // manager will handle it |
|
194 | // manager will handle it | |
195 |
if (shortcuts.handles(event)) { |
|
195 | if (shortcuts.handles(event)) { | |
196 |
return true; |
|
196 | return true; | |
197 | } |
|
197 | } | |
198 |
|
198 | |||
199 | return false; |
|
199 | return false; | |
200 | }; |
|
200 | }; | |
201 |
|
201 | |||
202 |
|
202 | |||
203 | /** |
|
203 | /** | |
204 | * Triger typsetting of math by mathjax on current cell element |
|
204 | * Triger typsetting of math by mathjax on current cell element | |
205 | * @method typeset |
|
205 | * @method typeset | |
206 | */ |
|
206 | */ | |
207 | Cell.prototype.typeset = function () { |
|
207 | Cell.prototype.typeset = function () { | |
208 | if (window.MathJax) { |
|
208 | if (window.MathJax) { | |
209 | var cell_math = this.element.get(0); |
|
209 | var cell_math = this.element.get(0); | |
210 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]); |
|
210 | MathJax.Hub.Queue(["Typeset", MathJax.Hub, cell_math]); | |
211 | } |
|
211 | } | |
212 | }; |
|
212 | }; | |
213 |
|
213 | |||
214 | /** |
|
214 | /** | |
215 | * handle cell level logic when a cell is selected |
|
215 | * handle cell level logic when a cell is selected | |
216 | * @method select |
|
216 | * @method select | |
217 | * @return is the action being taken |
|
217 | * @return is the action being taken | |
218 | */ |
|
218 | */ | |
219 | Cell.prototype.select = function () { |
|
219 | Cell.prototype.select = function () { | |
220 | if (!this.selected) { |
|
220 | if (!this.selected) { | |
221 | this.element.addClass('selected'); |
|
221 | this.element.addClass('selected'); | |
222 | this.element.removeClass('unselected'); |
|
222 | this.element.removeClass('unselected'); | |
223 | this.selected = true; |
|
223 | this.selected = true; | |
224 | return true; |
|
224 | return true; | |
225 | } else { |
|
225 | } else { | |
226 | return false; |
|
226 | return false; | |
227 | } |
|
227 | } | |
228 | }; |
|
228 | }; | |
229 |
|
229 | |||
230 | /** |
|
230 | /** | |
231 | * handle cell level logic when a cell is unselected |
|
231 | * handle cell level logic when a cell is unselected | |
232 | * @method unselect |
|
232 | * @method unselect | |
233 | * @return is the action being taken |
|
233 | * @return is the action being taken | |
234 | */ |
|
234 | */ | |
235 | Cell.prototype.unselect = function () { |
|
235 | Cell.prototype.unselect = function () { | |
236 | if (this.selected) { |
|
236 | if (this.selected) { | |
237 | this.element.addClass('unselected'); |
|
237 | this.element.addClass('unselected'); | |
238 | this.element.removeClass('selected'); |
|
238 | this.element.removeClass('selected'); | |
239 | this.selected = false; |
|
239 | this.selected = false; | |
240 | return true; |
|
240 | return true; | |
241 | } else { |
|
241 | } else { | |
242 | return false; |
|
242 | return false; | |
243 | } |
|
243 | } | |
244 | }; |
|
244 | }; | |
245 |
|
245 | |||
246 | /** |
|
246 | /** | |
247 | * handle cell level logic when a cell is rendered |
|
247 | * handle cell level logic when a cell is rendered | |
248 | * @method render |
|
248 | * @method render | |
249 | * @return is the action being taken |
|
249 | * @return is the action being taken | |
250 | */ |
|
250 | */ | |
251 | Cell.prototype.render = function () { |
|
251 | Cell.prototype.render = function () { | |
252 | if (!this.rendered) { |
|
252 | if (!this.rendered) { | |
253 | this.element.addClass('rendered'); |
|
253 | this.element.addClass('rendered'); | |
254 | this.element.removeClass('unrendered'); |
|
254 | this.element.removeClass('unrendered'); | |
255 | this.rendered = true; |
|
255 | this.rendered = true; | |
256 | return true; |
|
256 | return true; | |
257 | } else { |
|
257 | } else { | |
258 | return false; |
|
258 | return false; | |
259 | } |
|
259 | } | |
260 | }; |
|
260 | }; | |
261 |
|
261 | |||
262 | /** |
|
262 | /** | |
263 | * handle cell level logic when a cell is unrendered |
|
263 | * handle cell level logic when a cell is unrendered | |
264 | * @method unrender |
|
264 | * @method unrender | |
265 | * @return is the action being taken |
|
265 | * @return is the action being taken | |
266 | */ |
|
266 | */ | |
267 | Cell.prototype.unrender = function () { |
|
267 | Cell.prototype.unrender = function () { | |
268 | if (this.rendered) { |
|
268 | if (this.rendered) { | |
269 | this.element.addClass('unrendered'); |
|
269 | this.element.addClass('unrendered'); | |
270 | this.element.removeClass('rendered'); |
|
270 | this.element.removeClass('rendered'); | |
271 | this.rendered = false; |
|
271 | this.rendered = false; | |
272 | return true; |
|
272 | return true; | |
273 | } else { |
|
273 | } else { | |
274 | return false; |
|
274 | return false; | |
275 | } |
|
275 | } | |
276 | }; |
|
276 | }; | |
277 |
|
277 | |||
278 | /** |
|
278 | /** | |
279 | * Delegates keyboard shortcut handling to either IPython keyboard |
|
279 | * Delegates keyboard shortcut handling to either IPython keyboard | |
280 | * manager when in command mode, or CodeMirror when in edit mode |
|
280 | * manager when in command mode, or CodeMirror when in edit mode | |
281 | * |
|
281 | * | |
282 | * @method handle_keyevent |
|
282 | * @method handle_keyevent | |
283 | * @param {CodeMirror} editor - The codemirror instance bound to the cell |
|
283 | * @param {CodeMirror} editor - The codemirror instance bound to the cell | |
284 | * @param {event} - key event to be handled |
|
284 | * @param {event} - key event to be handled | |
285 | * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise |
|
285 | * @return {Boolean} `true` if CodeMirror should ignore the event, `false` Otherwise | |
286 | */ |
|
286 | */ | |
287 | Cell.prototype.handle_keyevent = function (editor, event) { |
|
287 | Cell.prototype.handle_keyevent = function (editor, event) { | |
288 | if (this.mode === 'command') { |
|
288 | if (this.mode === 'command') { | |
289 | return true; |
|
289 | return true; | |
290 | } else if (this.mode === 'edit') { |
|
290 | } else if (this.mode === 'edit') { | |
291 | return this.handle_codemirror_keyevent(editor, event); |
|
291 | return this.handle_codemirror_keyevent(editor, event); | |
292 | } |
|
292 | } | |
293 | }; |
|
293 | }; | |
294 |
|
294 | |||
295 | /** |
|
295 | /** | |
296 | * @method at_top |
|
296 | * @method at_top | |
297 | * @return {Boolean} |
|
297 | * @return {Boolean} | |
298 | */ |
|
298 | */ | |
299 | Cell.prototype.at_top = function () { |
|
299 | Cell.prototype.at_top = function () { | |
300 | var cm = this.code_mirror; |
|
300 | var cm = this.code_mirror; | |
301 | var cursor = cm.getCursor(); |
|
301 | var cursor = cm.getCursor(); | |
302 | if (cursor.line === 0 && cursor.ch === 0) { |
|
302 | if (cursor.line === 0 && cursor.ch === 0) { | |
303 | return true; |
|
303 | return true; | |
304 | } |
|
304 | } | |
305 | return false; |
|
305 | return false; | |
306 | }; |
|
306 | }; | |
307 |
|
307 | |||
308 | /** |
|
308 | /** | |
309 | * @method at_bottom |
|
309 | * @method at_bottom | |
310 | * @return {Boolean} |
|
310 | * @return {Boolean} | |
311 | * */ |
|
311 | * */ | |
312 | Cell.prototype.at_bottom = function () { |
|
312 | Cell.prototype.at_bottom = function () { | |
313 | var cm = this.code_mirror; |
|
313 | var cm = this.code_mirror; | |
314 | var cursor = cm.getCursor(); |
|
314 | var cursor = cm.getCursor(); | |
315 | if (cursor.line === (cm.lineCount()-1) && cursor.ch === cm.getLine(cursor.line).length) { |
|
315 | if (cursor.line === (cm.lineCount()-1) && cursor.ch === cm.getLine(cursor.line).length) { | |
316 | return true; |
|
316 | return true; | |
317 | } |
|
317 | } | |
318 | return false; |
|
318 | return false; | |
319 | }; |
|
319 | }; | |
320 |
|
320 | |||
321 | /** |
|
321 | /** | |
322 | * enter the command mode for the cell |
|
322 | * enter the command mode for the cell | |
323 | * @method command_mode |
|
323 | * @method command_mode | |
324 | * @return is the action being taken |
|
324 | * @return is the action being taken | |
325 | */ |
|
325 | */ | |
326 | Cell.prototype.command_mode = function () { |
|
326 | Cell.prototype.command_mode = function () { | |
327 | if (this.mode !== 'command') { |
|
327 | if (this.mode !== 'command') { | |
328 | this.element.addClass('command_mode'); |
|
328 | this.element.addClass('command_mode'); | |
329 | this.element.removeClass('edit_mode'); |
|
329 | this.element.removeClass('edit_mode'); | |
330 | this.mode = 'command'; |
|
330 | this.mode = 'command'; | |
331 | return true; |
|
331 | return true; | |
332 | } else { |
|
332 | } else { | |
333 | return false; |
|
333 | return false; | |
334 | } |
|
334 | } | |
335 | }; |
|
335 | }; | |
336 |
|
336 | |||
337 | /** |
|
337 | /** | |
338 | * enter the edit mode for the cell |
|
338 | * enter the edit mode for the cell | |
339 | * @method command_mode |
|
339 | * @method command_mode | |
340 | * @return is the action being taken |
|
340 | * @return is the action being taken | |
341 | */ |
|
341 | */ | |
342 | Cell.prototype.edit_mode = function () { |
|
342 | Cell.prototype.edit_mode = function () { | |
343 | if (this.mode !== 'edit') { |
|
343 | if (this.mode !== 'edit') { | |
344 | this.element.addClass('edit_mode'); |
|
344 | this.element.addClass('edit_mode'); | |
345 | this.element.removeClass('command_mode'); |
|
345 | this.element.removeClass('command_mode'); | |
346 | this.mode = 'edit'; |
|
346 | this.mode = 'edit'; | |
347 | return true; |
|
347 | return true; | |
348 | } else { |
|
348 | } else { | |
349 | return false; |
|
349 | return false; | |
350 | } |
|
350 | } | |
351 | }; |
|
351 | }; | |
352 |
|
352 | |||
353 | /** |
|
353 | /** | |
354 | * Focus the cell in the DOM sense |
|
354 | * Focus the cell in the DOM sense | |
355 | * @method focus_cell |
|
355 | * @method focus_cell | |
356 | */ |
|
356 | */ | |
357 | Cell.prototype.focus_cell = function () { |
|
357 | Cell.prototype.focus_cell = function () { | |
358 | this.element.focus(); |
|
358 | this.element.focus(); | |
359 | }; |
|
359 | }; | |
360 |
|
360 | |||
361 | /** |
|
361 | /** | |
362 | * Focus the editor area so a user can type |
|
362 | * Focus the editor area so a user can type | |
363 | * |
|
363 | * | |
364 | * NOTE: If codemirror is focused via a mouse click event, you don't want to |
|
364 | * NOTE: If codemirror is focused via a mouse click event, you don't want to | |
365 | * call this because it will cause a page jump. |
|
365 | * call this because it will cause a page jump. | |
366 | * @method focus_editor |
|
366 | * @method focus_editor | |
367 | */ |
|
367 | */ | |
368 | Cell.prototype.focus_editor = function () { |
|
368 | Cell.prototype.focus_editor = function () { | |
369 | this.refresh(); |
|
369 | this.refresh(); | |
370 | this.code_mirror.focus(); |
|
370 | this.code_mirror.focus(); | |
371 | }; |
|
371 | }; | |
372 |
|
372 | |||
373 | /** |
|
373 | /** | |
374 | * Refresh codemirror instance |
|
374 | * Refresh codemirror instance | |
375 | * @method refresh |
|
375 | * @method refresh | |
376 | */ |
|
376 | */ | |
377 | Cell.prototype.refresh = function () { |
|
377 | Cell.prototype.refresh = function () { | |
378 | this.code_mirror.refresh(); |
|
378 | this.code_mirror.refresh(); | |
379 | }; |
|
379 | }; | |
380 |
|
380 | |||
381 | /** |
|
381 | /** | |
382 | * should be overritten by subclass |
|
382 | * should be overritten by subclass | |
383 | * @method get_text |
|
383 | * @method get_text | |
384 | */ |
|
384 | */ | |
385 | Cell.prototype.get_text = function () { |
|
385 | Cell.prototype.get_text = function () { | |
386 | }; |
|
386 | }; | |
387 |
|
387 | |||
388 | /** |
|
388 | /** | |
389 | * should be overritten by subclass |
|
389 | * should be overritten by subclass | |
390 | * @method set_text |
|
390 | * @method set_text | |
391 | * @param {string} text |
|
391 | * @param {string} text | |
392 | */ |
|
392 | */ | |
393 | Cell.prototype.set_text = function (text) { |
|
393 | Cell.prototype.set_text = function (text) { | |
394 | }; |
|
394 | }; | |
395 |
|
395 | |||
396 | /** |
|
396 | /** | |
397 | * should be overritten by subclass |
|
397 | * should be overritten by subclass | |
398 | * serialise cell to json. |
|
398 | * serialise cell to json. | |
399 | * @method toJSON |
|
399 | * @method toJSON | |
400 | **/ |
|
400 | **/ | |
401 | Cell.prototype.toJSON = function () { |
|
401 | Cell.prototype.toJSON = function () { | |
402 | var data = {}; |
|
402 | var data = {}; | |
403 | // deepcopy the metadata so copied cells don't share the same object |
|
403 | // deepcopy the metadata so copied cells don't share the same object | |
404 | data.metadata = JSON.parse(JSON.stringify(this.metadata)); |
|
404 | data.metadata = JSON.parse(JSON.stringify(this.metadata)); | |
405 | data.cell_type = this.cell_type; |
|
405 | data.cell_type = this.cell_type; | |
406 | return data; |
|
406 | return data; | |
407 | }; |
|
407 | }; | |
408 |
|
408 | |||
409 |
|
409 | |||
410 | /** |
|
410 | /** | |
411 | * should be overritten by subclass |
|
411 | * should be overritten by subclass | |
412 | * @method fromJSON |
|
412 | * @method fromJSON | |
413 | **/ |
|
413 | **/ | |
414 | Cell.prototype.fromJSON = function (data) { |
|
414 | Cell.prototype.fromJSON = function (data) { | |
415 | if (data.metadata !== undefined) { |
|
415 | if (data.metadata !== undefined) { | |
416 | this.metadata = data.metadata; |
|
416 | this.metadata = data.metadata; | |
417 | } |
|
417 | } | |
418 | this.celltoolbar.rebuild(); |
|
418 | this.celltoolbar.rebuild(); | |
419 | }; |
|
419 | }; | |
420 |
|
420 | |||
421 |
|
421 | |||
422 | /** |
|
422 | /** | |
423 | * can the cell be split into two cells (false if not deletable) |
|
423 | * can the cell be split into two cells (false if not deletable) | |
424 | * @method is_splittable |
|
424 | * @method is_splittable | |
425 | **/ |
|
425 | **/ | |
426 | Cell.prototype.is_splittable = function () { |
|
426 | Cell.prototype.is_splittable = function () { | |
427 | return this.is_deletable(); |
|
427 | return this.is_deletable(); | |
428 | }; |
|
428 | }; | |
429 |
|
429 | |||
430 |
|
430 | |||
431 | /** |
|
431 | /** | |
432 | * can the cell be merged with other cells (false if not deletable) |
|
432 | * can the cell be merged with other cells (false if not deletable) | |
433 | * @method is_mergeable |
|
433 | * @method is_mergeable | |
434 | **/ |
|
434 | **/ | |
435 | Cell.prototype.is_mergeable = function () { |
|
435 | Cell.prototype.is_mergeable = function () { | |
436 | return this.is_deletable(); |
|
436 | return this.is_deletable(); | |
437 | }; |
|
437 | }; | |
438 |
|
438 | |||
439 | /** |
|
439 | /** | |
440 | * is the cell deletable? only false (undeletable) if |
|
440 | * is the cell deletable? only false (undeletable) if | |
441 | * metadata.deletable is explicitly false -- everything else |
|
441 | * metadata.deletable is explicitly false -- everything else | |
442 | * counts as true |
|
442 | * counts as true | |
443 | * |
|
443 | * | |
444 | * @method is_deletable |
|
444 | * @method is_deletable | |
445 | **/ |
|
445 | **/ | |
446 | Cell.prototype.is_deletable = function () { |
|
446 | Cell.prototype.is_deletable = function () { | |
447 | if (this.metadata.deletable === false) { |
|
447 | if (this.metadata.deletable === false) { | |
448 | return false; |
|
448 | return false; | |
449 | } |
|
449 | } | |
450 | return true; |
|
450 | return true; | |
451 | }; |
|
451 | }; | |
452 |
|
452 | |||
453 | /** |
|
453 | /** | |
454 | * @return {String} - the text before the cursor |
|
454 | * @return {String} - the text before the cursor | |
455 | * @method get_pre_cursor |
|
455 | * @method get_pre_cursor | |
456 | **/ |
|
456 | **/ | |
457 | Cell.prototype.get_pre_cursor = function () { |
|
457 | Cell.prototype.get_pre_cursor = function () { | |
458 | var cursor = this.code_mirror.getCursor(); |
|
458 | var cursor = this.code_mirror.getCursor(); | |
459 | var text = this.code_mirror.getRange({line:0, ch:0}, cursor); |
|
459 | var text = this.code_mirror.getRange({line:0, ch:0}, cursor); | |
460 | text = text.replace(/^\n+/, '').replace(/\n+$/, ''); |
|
460 | text = text.replace(/^\n+/, '').replace(/\n+$/, ''); | |
461 | return text; |
|
461 | return text; | |
462 | }; |
|
462 | }; | |
463 |
|
463 | |||
464 |
|
464 | |||
465 | /** |
|
465 | /** | |
466 | * @return {String} - the text after the cursor |
|
466 | * @return {String} - the text after the cursor | |
467 | * @method get_post_cursor |
|
467 | * @method get_post_cursor | |
468 | **/ |
|
468 | **/ | |
469 | Cell.prototype.get_post_cursor = function () { |
|
469 | Cell.prototype.get_post_cursor = function () { | |
470 | var cursor = this.code_mirror.getCursor(); |
|
470 | var cursor = this.code_mirror.getCursor(); | |
471 | var last_line_num = this.code_mirror.lineCount()-1; |
|
471 | var last_line_num = this.code_mirror.lineCount()-1; | |
472 | var last_line_len = this.code_mirror.getLine(last_line_num).length; |
|
472 | var last_line_len = this.code_mirror.getLine(last_line_num).length; | |
473 | var end = {line:last_line_num, ch:last_line_len}; |
|
473 | var end = {line:last_line_num, ch:last_line_len}; | |
474 | var text = this.code_mirror.getRange(cursor, end); |
|
474 | var text = this.code_mirror.getRange(cursor, end); | |
475 | text = text.replace(/^\n+/, '').replace(/\n+$/, ''); |
|
475 | text = text.replace(/^\n+/, '').replace(/\n+$/, ''); | |
476 | return text; |
|
476 | return text; | |
477 | }; |
|
477 | }; | |
478 |
|
478 | |||
479 | /** |
|
479 | /** | |
480 | * Show/Hide CodeMirror LineNumber |
|
480 | * Show/Hide CodeMirror LineNumber | |
481 | * @method show_line_numbers |
|
481 | * @method show_line_numbers | |
482 | * |
|
482 | * | |
483 | * @param value {Bool} show (true), or hide (false) the line number in CodeMirror |
|
483 | * @param value {Bool} show (true), or hide (false) the line number in CodeMirror | |
484 | **/ |
|
484 | **/ | |
485 | Cell.prototype.show_line_numbers = function (value) { |
|
485 | Cell.prototype.show_line_numbers = function (value) { | |
486 | this.code_mirror.setOption('lineNumbers', value); |
|
486 | this.code_mirror.setOption('lineNumbers', value); | |
487 | this.code_mirror.refresh(); |
|
487 | this.code_mirror.refresh(); | |
488 | }; |
|
488 | }; | |
489 |
|
489 | |||
490 | /** |
|
490 | /** | |
491 | * Toggle CodeMirror LineNumber |
|
491 | * Toggle CodeMirror LineNumber | |
492 | * @method toggle_line_numbers |
|
492 | * @method toggle_line_numbers | |
493 | **/ |
|
493 | **/ | |
494 | Cell.prototype.toggle_line_numbers = function () { |
|
494 | Cell.prototype.toggle_line_numbers = function () { | |
495 | var val = this.code_mirror.getOption('lineNumbers'); |
|
495 | var val = this.code_mirror.getOption('lineNumbers'); | |
496 | this.show_line_numbers(!val); |
|
496 | this.show_line_numbers(!val); | |
497 | }; |
|
497 | }; | |
498 |
|
498 | |||
499 | /** |
|
499 | /** | |
500 | * Force codemirror highlight mode |
|
500 | * Force codemirror highlight mode | |
501 | * @method force_highlight |
|
501 | * @method force_highlight | |
502 | * @param {object} - CodeMirror mode |
|
502 | * @param {object} - CodeMirror mode | |
503 | **/ |
|
503 | **/ | |
504 | Cell.prototype.force_highlight = function(mode) { |
|
504 | Cell.prototype.force_highlight = function(mode) { | |
505 | this.user_highlight = mode; |
|
505 | this.user_highlight = mode; | |
506 | this.auto_highlight(); |
|
506 | this.auto_highlight(); | |
507 | }; |
|
507 | }; | |
508 |
|
508 | |||
509 | /** |
|
509 | /** | |
510 | * Try to autodetect cell highlight mode, or use selected mode |
|
510 | * Try to autodetect cell highlight mode, or use selected mode | |
511 | * @methods _auto_highlight |
|
511 | * @methods _auto_highlight | |
512 | * @private |
|
512 | * @private | |
513 | * @param {String|object|undefined} - CodeMirror mode | 'auto' |
|
513 | * @param {String|object|undefined} - CodeMirror mode | 'auto' | |
514 | **/ |
|
514 | **/ | |
515 | Cell.prototype._auto_highlight = function (modes) { |
|
515 | Cell.prototype._auto_highlight = function (modes) { | |
516 | //Here we handle manually selected modes |
|
516 | //Here we handle manually selected modes | |
517 | var that = this; |
|
517 | var that = this; | |
518 | var mode; |
|
518 | var mode; | |
519 | if( this.user_highlight !== undefined && this.user_highlight != 'auto' ) |
|
519 | if( this.user_highlight !== undefined && this.user_highlight != 'auto' ) | |
520 | { |
|
520 | { | |
521 | mode = this.user_highlight; |
|
521 | mode = this.user_highlight; | |
522 | CodeMirror.autoLoadMode(this.code_mirror, mode); |
|
522 | CodeMirror.autoLoadMode(this.code_mirror, mode); | |
523 | this.code_mirror.setOption('mode', mode); |
|
523 | this.code_mirror.setOption('mode', mode); | |
524 | return; |
|
524 | return; | |
525 | } |
|
525 | } | |
526 | var current_mode = this.code_mirror.getOption('mode', mode); |
|
526 | var current_mode = this.code_mirror.getOption('mode', mode); | |
527 | var first_line = this.code_mirror.getLine(0); |
|
527 | var first_line = this.code_mirror.getLine(0); | |
528 | // loop on every pairs |
|
528 | // loop on every pairs | |
529 | for(mode in modes) { |
|
529 | for(mode in modes) { | |
530 | var regs = modes[mode].reg; |
|
530 | var regs = modes[mode].reg; | |
531 | // only one key every time but regexp can't be keys... |
|
531 | // only one key every time but regexp can't be keys... | |
532 | for(var i=0; i<regs.length; i++) { |
|
532 | for(var i=0; i<regs.length; i++) { | |
533 | // here we handle non magic_modes |
|
533 | // here we handle non magic_modes | |
534 | if(first_line.match(regs[i]) !== null) { |
|
534 | if(first_line.match(regs[i]) !== null) { | |
535 | if(current_mode == mode){ |
|
535 | if(current_mode == mode){ | |
536 | return; |
|
536 | return; | |
537 | } |
|
537 | } | |
538 | if (mode.search('magic_') !== 0) { |
|
538 | if (mode.search('magic_') !== 0) { | |
539 | utils.requireCodeMirrorMode(mode, function () { |
|
539 | utils.requireCodeMirrorMode(mode, function () { | |
540 | that.code_mirror.setOption('mode', mode); |
|
540 | that.code_mirror.setOption('mode', mode); | |
541 | }); |
|
541 | }); | |
542 | return; |
|
542 | return; | |
543 | } |
|
543 | } | |
544 | var open = modes[mode].open || "%%"; |
|
544 | var open = modes[mode].open || "%%"; | |
545 | var close = modes[mode].close || "%%end"; |
|
545 | var close = modes[mode].close || "%%end"; | |
546 | var mmode = mode; |
|
546 | var magic_mode = mode; | |
547 | mode = mmode.substr(6); |
|
547 | mode = magic_mode.substr(6); | |
548 | if(current_mode == mmode){ |
|
548 | if(current_mode == magic_mode){ | |
549 | return; |
|
549 | return; | |
550 | } |
|
550 | } | |
551 | utils.requireCodeMirrorMode(mode, function () { |
|
551 | utils.requireCodeMirrorMode(mode, function () { | |
552 | // create on the fly a mode that switch between |
|
552 | // create on the fly a mode that switch between | |
553 | // plain/text and something else, otherwise `%%` is |
|
553 | // plain/text and something else, otherwise `%%` is | |
554 | // source of some highlight issues. |
|
554 | // source of some highlight issues. | |
555 | CodeMirror.defineMode(mmode, function(config) { |
|
555 | CodeMirror.defineMode(magic_mode, function(config) { | |
556 | return CodeMirror.multiplexingMode( |
|
556 | return CodeMirror.multiplexingMode( | |
557 | CodeMirror.getMode(config, 'text/plain'), |
|
557 | CodeMirror.getMode(config, 'text/plain'), | |
558 | // always set someting on close |
|
558 | // always set something on close | |
559 | {open: open, close: close, |
|
559 | {open: open, close: close, | |
560 | mode: CodeMirror.getMode(config, mode), |
|
560 | mode: CodeMirror.getMode(config, mode), | |
561 | delimStyle: "delimit" |
|
561 | delimStyle: "delimit" | |
562 | } |
|
562 | } | |
563 | ); |
|
563 | ); | |
564 | }); |
|
564 | }); | |
565 | that.code_mirror.setOption('mode', mmode); |
|
565 | that.code_mirror.setOption('mode', magic_mode); | |
566 | }); |
|
566 | }); | |
567 | return; |
|
567 | return; | |
568 | } |
|
568 | } | |
569 | } |
|
569 | } | |
570 | } |
|
570 | } | |
571 | // fallback on default |
|
571 | // fallback on default | |
572 | var default_mode; |
|
572 | var default_mode; | |
573 | try { |
|
573 | try { | |
574 | default_mode = this._options.cm_config.mode; |
|
574 | default_mode = this._options.cm_config.mode; | |
575 | } catch(e) { |
|
575 | } catch(e) { | |
576 | default_mode = 'text/plain'; |
|
576 | default_mode = 'text/plain'; | |
577 | } |
|
577 | } | |
578 | if( current_mode === default_mode){ |
|
578 | if( current_mode === default_mode){ | |
579 | return; |
|
579 | return; | |
580 | } |
|
580 | } | |
581 | this.code_mirror.setOption('mode', default_mode); |
|
581 | this.code_mirror.setOption('mode', default_mode); | |
582 | }; |
|
582 | }; | |
583 |
|
583 | |||
584 | // Backwards compatibility. |
|
584 | // Backwards compatibility. | |
585 | IPython.Cell = Cell; |
|
585 | IPython.Cell = Cell; | |
586 |
|
586 | |||
587 | return {'Cell': Cell}; |
|
587 | return {'Cell': Cell}; | |
588 | }); |
|
588 | }); |
@@ -1,39 +1,38 | |||||
1 | // IPython mode is just a slightly altered Python Mode with `?` beeing a extra |
|
1 | // IPython mode is just a slightly altered Python Mode with `?` beeing a extra | |
2 | // single operator. Here we define `ipython` mode in the require `python` |
|
2 | // single operator. Here we define `ipython` mode in the require `python` | |
3 | // callback to auto-load python mode, which is more likely not the best things |
|
3 | // callback to auto-load python mode, which is more likely not the best things | |
4 | // to do, but at least the simple one for now. |
|
4 | // to do, but at least the simple one for now. | |
5 |
|
5 | |||
6 | (function(mod) { |
|
6 | (function(mod) { | |
7 | if (typeof exports == "object" && typeof module == "object"){ // CommonJS |
|
7 | if (typeof exports == "object" && typeof module == "object"){ // CommonJS | |
8 |
mod(require("codemirror/lib/codemirror"), |
|
8 | mod(require("codemirror/lib/codemirror"), | |
9 | require("codemirror/mode/python/python") |
|
9 | require("codemirror/mode/python/python") | |
10 | ); |
|
10 | ); | |
11 | } else if (typeof define == "function" && define.amd){ // AMD |
|
11 | } else if (typeof define == "function" && define.amd){ // AMD | |
12 |
define(["codemirror/lib/codemirror", |
|
12 | define(["codemirror/lib/codemirror", | |
13 | "codemirror/mode/python/python"], mod); |
|
13 | "codemirror/mode/python/python"], mod); | |
14 | } else {// Plain browser env |
|
14 | } else {// Plain browser env | |
15 | mod(CodeMirror); |
|
15 | mod(CodeMirror); | |
16 | } |
|
16 | } | |
17 | })(function(CodeMirror) { |
|
17 | })(function(CodeMirror) { | |
18 | "use strict"; |
|
18 | "use strict"; | |
19 |
|
19 | |||
20 | CodeMirror.defineMode("ipython", function(conf, parserConf) { |
|
20 | CodeMirror.defineMode("ipython", function(conf, parserConf) { | |
21 | var pythonConf = {}; |
|
21 | var pythonConf = {}; | |
22 | for (var prop in parserConf) { |
|
22 | for (var prop in parserConf) { | |
23 | if (parserConf.hasOwnProperty(prop)) { |
|
23 | if (parserConf.hasOwnProperty(prop)) { | |
24 | pythonConf[prop] = parserConf[prop]; |
|
24 | pythonConf[prop] = parserConf[prop]; | |
25 | } |
|
25 | } | |
26 | } |
|
26 | } | |
27 | pythonConf.name = 'python'; |
|
27 | pythonConf.name = 'python'; | |
28 | pythonConf.singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\\?]"); |
|
28 | pythonConf.singleOperators = new RegExp("^[\\+\\-\\*/%&|\\^~<>!\\?]"); | |
29 | if (pythonConf.version === 3) { |
|
29 | if (pythonConf.version === 3) { | |
30 | pythonConf.identifiers = new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*"); |
|
30 | pythonConf.identifiers = new RegExp("^[_A-Za-z\u00A1-\uFFFF][_A-Za-z0-9\u00A1-\uFFFF]*"); | |
31 | } else if (pythonConf.version === 2) { |
|
31 | } else if (pythonConf.version === 2) { | |
32 | pythonConf.identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); |
|
32 | pythonConf.identifiers = new RegExp("^[_A-Za-z][_A-Za-z0-9]*"); | |
33 | } |
|
33 | } | |
34 | return CodeMirror.getMode(conf, pythonConf); |
|
34 | return CodeMirror.getMode(conf, pythonConf); | |
35 | }, 'python'); |
|
35 | }, 'python'); | |
36 |
|
36 | |||
37 | CodeMirror.defineMIME("text/x-ipython", "ipython"); |
|
37 | CodeMirror.defineMIME("text/x-ipython", "ipython"); | |
38 | }) |
|
38 | }) | |
39 |
|
@@ -1,64 +1,62 | |||||
1 |
// IPython GFM (GitHub Flavored Markdown) mode is just a slightly altered GFM |
|
1 | // IPython GFM (GitHub Flavored Markdown) mode is just a slightly altered GFM | |
2 |
// Mode with support for latex. |
|
2 | // Mode with support for latex. | |
3 | // |
|
3 | // | |
4 |
// Latex support was supported by Codemirror GFM as of |
|
4 | // Latex support was supported by Codemirror GFM as of | |
5 | // https://github.com/codemirror/CodeMirror/pull/567 |
|
5 | // https://github.com/codemirror/CodeMirror/pull/567 | |
6 | // But was later removed in |
|
6 | // But was later removed in | |
7 | // https://github.com/codemirror/CodeMirror/commit/d9c9f1b1ffe984aee41307f3e927f80d1f23590c |
|
7 | // https://github.com/codemirror/CodeMirror/commit/d9c9f1b1ffe984aee41307f3e927f80d1f23590c | |
8 |
|
8 | |||
9 |
|
9 | |||
10 | (function(mod) { |
|
10 | (function(mod) { | |
11 | if (typeof exports == "object" && typeof module == "object"){ // CommonJS |
|
11 | if (typeof exports == "object" && typeof module == "object"){ // CommonJS | |
12 | mod(require("codemirror/lib/codemirror") |
|
12 | mod(require("codemirror/lib/codemirror") | |
13 | ,require("codemirror/addon/mode/multiplex") |
|
13 | ,require("codemirror/addon/mode/multiplex") | |
14 | ,require("codemirror/mode/gfm/gfm") |
|
14 | ,require("codemirror/mode/gfm/gfm") | |
15 | ,require("codemirror/mode/stex/stex") |
|
15 | ,require("codemirror/mode/stex/stex") | |
16 | ); |
|
16 | ); | |
17 | } else if (typeof define == "function" && define.amd){ // AMD |
|
17 | } else if (typeof define == "function" && define.amd){ // AMD | |
18 |
define(["codemirror/lib/codemirror" |
|
18 | define(["codemirror/lib/codemirror" | |
19 | ,"codemirror/addon/mode/multiplex" |
|
19 | ,"codemirror/addon/mode/multiplex" | |
20 | ,"codemirror/mode/python/python" |
|
20 | ,"codemirror/mode/python/python" | |
21 | ,"codemirror/mode/stex/stex" |
|
21 | ,"codemirror/mode/stex/stex" | |
22 | ], mod); |
|
22 | ], mod); | |
23 | } else {// Plain browser env |
|
23 | } else {// Plain browser env | |
24 | mod(CodeMirror); |
|
24 | mod(CodeMirror); | |
25 | } |
|
25 | } | |
26 | })( function(CodeMirror){ |
|
26 | })( function(CodeMirror){ | |
27 | "use strict"; |
|
27 | "use strict"; | |
28 |
|
28 | |||
29 | CodeMirror.defineMode("ipythongfm", function(config, parserConfig) { |
|
29 | CodeMirror.defineMode("ipythongfm", function(config, parserConfig) { | |
30 |
|
30 | |||
31 | var gfm_mode = CodeMirror.getMode(config, "gfm"); |
|
31 | var gfm_mode = CodeMirror.getMode(config, "gfm"); | |
32 | var tex_mode = CodeMirror.getMode(config, "stex"); |
|
32 | var tex_mode = CodeMirror.getMode(config, "stex"); | |
33 |
|
33 | |||
34 | return CodeMirror.multiplexingMode( |
|
34 | return CodeMirror.multiplexingMode( | |
35 | gfm_mode, |
|
35 | gfm_mode, | |
36 | { |
|
36 | { | |
37 | open: "$", close: "$", |
|
37 | open: "$", close: "$", | |
38 | mode: tex_mode, |
|
38 | mode: tex_mode, | |
39 | delimStyle: "delimit" |
|
39 | delimStyle: "delimit" | |
40 | }, |
|
40 | }, | |
41 | { |
|
41 | { | |
42 | // not sure this works as $$ is interpreted at (opening $, closing $, as defined just above) |
|
42 | // not sure this works as $$ is interpreted at (opening $, closing $, as defined just above) | |
43 | open: "$$", close: "$$", |
|
43 | open: "$$", close: "$$", | |
44 | mode: tex_mode, |
|
44 | mode: tex_mode, | |
45 | delimStyle: "delimit" |
|
45 | delimStyle: "delimit" | |
46 | }, |
|
46 | }, | |
47 | { |
|
47 | { | |
48 | open: "\\(", close: "\\)", |
|
48 | open: "\\(", close: "\\)", | |
49 | mode: tex_mode, |
|
49 | mode: tex_mode, | |
50 | delimStyle: "delimit" |
|
50 | delimStyle: "delimit" | |
51 | }, |
|
51 | }, | |
52 | { |
|
52 | { | |
53 | open: "\\[", close: "\\]", |
|
53 | open: "\\[", close: "\\]", | |
54 | mode: tex_mode, |
|
54 | mode: tex_mode, | |
55 | delimStyle: "delimit" |
|
55 | delimStyle: "delimit" | |
56 | } |
|
56 | } | |
57 | // .. more multiplexed styles can follow here |
|
57 | // .. more multiplexed styles can follow here | |
58 | ); |
|
58 | ); | |
59 | }, 'gfm'); |
|
59 | }, 'gfm'); | |
60 |
|
60 | |||
61 | CodeMirror.defineMIME("text/x-ipythongfm", "ipythongfm"); |
|
61 | CodeMirror.defineMIME("text/x-ipythongfm", "ipythongfm"); | |
62 |
|
||||
63 |
|
||||
64 | }) |
|
62 | }) |
General Comments 0
You need to be logged in to leave comments.
Login now