##// END OF EJS Templates
Merge branch 'repr_html' of https://github.com/minrk/ipython into minrk-repr_html
Brian E. Granger -
r4407:a65c2d31 merge
parent child Browse files
Show More
@@ -1,375 +1,378 b''
1 1 /**
2 2 * HTML5 ✰ Boilerplate
3 3 *
4 4 * style.css contains a reset, font normalization and some base styles.
5 5 *
6 6 * Credit is left where credit is due.
7 7 * Much inspiration was taken from these projects:
8 8 * - yui.yahooapis.com/2.8.1/build/base/base.css
9 9 * - camendesign.com/design/
10 10 * - praegnanz.de/weblog/htmlcssjs-kickstart
11 11 */
12 12
13 13
14 14 /**
15 15 * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
16 16 * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
17 17 * html5doctor.com/html-5-reset-stylesheet/
18 18 */
19 19
20 20 html, body, div, span, object, iframe,
21 21 h1, h2, h3, h4, h5, h6, p, blockquote, pre,
22 22 abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
23 23 small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
24 24 fieldset, form, label, legend,
25 25 table, caption, tbody, tfoot, thead, tr, th, td,
26 26 article, aside, canvas, details, figcaption, figure,
27 27 footer, header, hgroup, menu, nav, section, summary,
28 28 time, mark, audio, video {
29 29 margin: 0;
30 30 padding: 0;
31 31 border: 0;
32 32 font-size: 100%;
33 33 font: inherit;
34 34 vertical-align: baseline;
35 35 }
36 36
37 37 article, aside, details, figcaption, figure,
38 38 footer, header, hgroup, menu, nav, section {
39 39 display: block;
40 40 }
41 41
42 42 blockquote, q { quotes: none; }
43 43
44 44 blockquote:before, blockquote:after,
45 45 q:before, q:after { content: ""; content: none; }
46 46
47 47 ins { background-color: #ff9; color: #000; text-decoration: none; }
48 48
49 49 mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
50 50
51 51 del { text-decoration: line-through; }
52 52
53 53 abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
54 54
55 55 table { border-collapse: collapse; border-spacing: 0; }
56 56
57 57 hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
58 58
59 59 input, select { vertical-align: middle; }
60 60
61 61
62 62 /**
63 63 * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
64 64 */
65 65
66 66 body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
67 67 select, input, textarea, button { font:99% sans-serif; }
68 68
69 69 /* Normalize monospace sizing:
70 70 en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
71 71 pre, code, kbd, samp { font-family: monospace, sans-serif; }
72 72
73 73
74 74 /**
75 75 * Primary styles
76 76 *
77 77 * Author: IPython Development Team
78 78 */
79 79
80 80
81 81 body {
82 82 background-color: white;
83 83 /* This makes sure that the body covers the entire window and needs to
84 84 be in a different element than the display: box in wrapper below */
85 85 position: absolute;
86 86 left: 0px;
87 87 right: 0px;
88 88 top: 0px;
89 89 bottom: 0px;
90 90 overflow: hidden;
91 91 }
92 92
93 93
94 94 div#header {
95 95 /* Initially hidden to prevent FLOUC */
96 96 display: none;
97 97 position: relative;
98 98 height: 45px;
99 99 padding: 5px;
100 100 margin: 0px;
101 101 width: 100%;
102 102 }
103 103
104 104 span#ipython_notebook {
105 105 position: absolute;
106 106 padding: 2px;
107 107 }
108 108
109 109 span#ipython_notebook h1 {
110 110 font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
111 111 font-size: 197%;
112 112 display: inline;
113 113 }
114 114
115 115 span#save_widget {
116 116 position: absolute;
117 117 left: 0px;
118 118 padding: 5px 0px;
119 119 margin: 0px 0px 0px 0px;
120 120 }
121 121
122 122 input#notebook_name {
123 123 height: 1em;
124 124 line-height: 1em;
125 125 padding: 5px;
126 126 }
127 127
128 128 span#kernel_status {
129 129 position: absolute;
130 130 padding: 8px 5px 5px 5px;
131 131 right: 10px;
132 132 font-weight: bold;
133 133 }
134 134
135 135 .status_idle {
136 136 color: gray;
137 137 }
138 138
139 139 .status_busy {
140 140 color: red;
141 141 }
142 142
143 143 .status_restarting {
144 144 color: black;
145 145 }
146 146
147 147 div#notebook_app {
148 148 /* Initially hidden to prevent FLOUC */
149 149 display: none;
150 150 width: 100%;
151 151 position: relative;
152 152 }
153 153
154 154 div#left_panel {
155 155 overflow-y: auto;
156 156 top: 0px;
157 157 left: 0px;
158 158 margin: 0px;
159 159 padding: 0px;
160 160 position: absolute;
161 161 }
162 162
163 163 h3.section_header {
164 164 padding: 5px;
165 165 }
166 166
167 167 div.section_content {
168 168 padding: 5px;
169 169 }
170 170
171 171
172 172 span.section_row_buttons > button {
173 173 width: 60px;
174 174 }
175 175
176 176 .section_row {
177 177 margin: 5px 0px;
178 178 }
179 179
180 180 .section_row_buttons {
181 181 float: right;
182 182 }
183 183
184 184 .section_row_header {
185 185 float: left;
186 186 font-size: 85%;
187 187 padding: 0.2em 0em;
188 188 font-weight: bold;
189 189 }
190 190
191 191 span.button_label {
192 192 padding: 0.2em 1em;
193 193 font-size: 77%;
194 194 float: right;
195 195 }
196 196
197 197 /* This is needed because FF was adding a 2px margin top and bottom. */
198 198 .section_row .ui-button {
199 199 margin-top: 0px;
200 200 margin-bottom: 0px;
201 201 }
202 202
203 203
204 204 .ui-button .ui-button-text {
205 205 padding: 0.2em 0.8em;
206 206 font-size: 77%;
207 207 }
208 208
209 209 div#left_panel_splitter {
210 210 width: 8px;
211 211 top: 0px;
212 212 left: 202px;
213 213 margin: 0px;
214 214 padding: 0px;
215 215 position: absolute;
216 216 }
217 217
218 218 div#notebook_panel {
219 219 /* The L margin will be set in the Javascript code*/
220 220 margin: 0px 0px 0px 0px;
221 221 padding: 0px;
222 222 }
223 223
224 224 div#notebook {
225 225 overflow-y: scroll;
226 226 overflow-x: auto;
227 227 width: 100%;
228 228 padding: 0px 15px 0px 15px;
229 229 margin: 0px
230 230 background-color: white;
231 231 }
232 232
233 233 div#pager_splitter {
234 234 height: 8px;
235 235 }
236 236
237 237 div#pager {
238 238 padding: 15px;
239 239 overflow: auto;
240 240 }
241 241
242 242 div.cell {
243 243 width: 100%;
244 244 padding: 5px;
245 245 /* This acts as a spacer between cells, that is outside the border */
246 246 margin: 15px 0px 15px 0px;
247 247 }
248 248
249 249 div.code_cell {
250 250 background-color: white;
251 251 }
252 252
253 253 div.prompt {
254 254 width: 80px;
255 255 padding: 0.4em;
256 256 margin: 0px;
257 257 font-family: monospace;
258 258 }
259 259
260 260 div.input_prompt {
261 261 color: navy;
262 262 }
263 263
264 264 div.output {
265 265 /* This is a spacer between the input and output of each cell */
266 266 margin-top: 15px;
267 267 }
268 268
269 269 div.output_prompt {
270 270 color: darkred;
271 271 }
272 272
273 273 div.output_area {
274 274 text-align: left;
275 275 color: black;
276 276 font-family: monospace;
277 277 }
278 278
279 279 div.output_stream {
280 280 padding: 0.4em;
281 281 }
282 282
283 283 div.output_latex {
284 284 /* Slightly bigger than the rest of the notebook */
285 285 font-size: 116%;
286 286 }
287 287
288 div.output_html {
289 }
290
288 291 div.output_png {
289 292 }
290 293
291 294 div.text_cell {
292 295 background-color: white;
293 296 }
294 297
295 298 textarea.text_cell_input {
296 299 /* Slightly bigger than the rest of the notebook */
297 300 font-size: 116%;
298 301 font-family: monospace;
299 302 outline: none;
300 303 resize: none;
301 304 width: inherit;
302 305 border-style: none;
303 306 padding: 0px;
304 307 margin: 0px;
305 308 color: black;
306 309 }
307 310
308 311 div.text_cell_render {
309 312 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
310 313 /* Slightly bigger than the rest of the notebook */
311 314 font-size: 116%;
312 315 outline: none;
313 316 resize: none;
314 317 width: inherit;
315 318 border-style: none;
316 319 padding: 5px;
317 320 color: black;
318 321 }
319 322
320 323 div.text_cell_render em {font-style: italic;}
321 324 div.text_cell_render strong {font-weight: bold;}
322 325 div.text_cell_render u {text-decoration: underline;}
323 326 div.text_cell_render :link { text-decoration: underline }
324 327 div.text_cell_render :visited { text-decoration: underline }
325 328 div.text_cell_render h1 {font-size: 197%; margin: .67em 0; font-weight: bold;}
326 329 div.text_cell_render h2 {font-size: 153.9%; margin: .75em 0; font-weight: bold;}
327 330 div.text_cell_render h3 {font-size: 116%; margin: .83em 0; font-weight: bold;}
328 331 div.text_cell_render h4 {margin: 1.12em 0; font-weight: bold;}
329 332 div.text_cell_render h5 {font-size: 85%.; margin: 1.5em 0; font-weight: bold;}
330 333 div.text_cell_render h6 {font-size: 77%; margin: 1.67em 0; font-weight: bold;}
331 334 div.text_cell_render ul {list-style:disc; margin-left: 40px;}
332 335 div.text_cell_render ul ul {list-style:square; margin-left: 40px;}
333 336 div.text_cell_render ul ul ul {list-style:circle; margin-left: 40px;}
334 337 div.text_cell_render ol {list-style:upper-roman; margin-left: 40px;}
335 338 div.text_cell_render ol ol {list-style:upper-alpha;}
336 339 div.text_cell_render ol ol ol {list-style:decimal;}
337 340 div.text_cell_render ol ol ol ol {list-style:lower-alpha;}
338 341 div.text_cell_render ol ol ol ol ol {list-style:lower-roman;}
339 342
340 343
341 344 .CodeMirror {
342 345 overflow: hidden; /* Changed from auto to remove scrollbar */
343 346 height: auto; /* Changed to auto to autogrow */
344 347 line-height: 1.231; /* Changed from 1em to our global default */
345 348 }
346 349
347 350 /* CSS font colors for translated ANSI colors. */
348 351
349 352
350 353 .ansiblack {color: black;}
351 354 .ansired {color: darkred;}
352 355 .ansigreen {color: darkgreen;}
353 356 .ansiyellow {color: brown;}
354 357 .ansiblue {color: darkblue;}
355 358 .ansipurple {color: darkviolet;}
356 359 .ansicyan {color: steelblue;}
357 360 .ansigrey {color: grey;}
358 361 .ansibold {font-weight: bold;}
359 362
360 363 .completions {
361 364 position: absolute;
362 365 z-index: 10;
363 366 overflow: auto;
364 367 border: 1px solid black;
365 368 }
366 369
367 370 .completions select {
368 371 background: white;
369 372 outline: none;
370 373 border: none;
371 374 padding: 0px;
372 375 margin: 0px;
373 376 font-family: monospace;
374 377 }
375 378
@@ -1,312 +1,323 b''
1 1
2 2 //============================================================================
3 3 // CodeCell
4 4 //============================================================================
5 5
6 6 var IPython = (function (IPython) {
7 7
8 8 var utils = IPython.utils;
9 9
10 10 var CodeCell = function (notebook) {
11 11 this.code_mirror = null;
12 12 this.input_prompt_number = ' ';
13 13 this.is_completing = false;
14 14 this.completion_cursor = null;
15 15 IPython.Cell.apply(this, arguments);
16 16 };
17 17
18 18
19 19 CodeCell.prototype = new IPython.Cell();
20 20
21 21
22 22 CodeCell.prototype.create_element = function () {
23 23 var cell = $('<div></div>').addClass('cell border-box-sizing code_cell vbox');
24 24 var input = $('<div></div>').addClass('input hbox');
25 25 input.append($('<div/>').addClass('prompt input_prompt'));
26 26 var input_area = $('<div/>').addClass('input_area box-flex1');
27 27 this.code_mirror = CodeMirror(input_area.get(0), {
28 28 indentUnit : 4,
29 29 enterMode : 'flat',
30 30 tabMode: 'shift',
31 31 onKeyEvent: $.proxy(this.handle_codemirror_keyevent,this)
32 32 });
33 33 input.append(input_area);
34 34 var output = $('<div></div>').addClass('output vbox');
35 35 cell.append(input).append(output);
36 36 this.element = cell;
37 37 this.collapse()
38 38 };
39 39
40 40
41 41 CodeCell.prototype.handle_codemirror_keyevent = function (editor, event) {
42 42 // This method gets called in CodeMirror's onKeyDown/onKeyPress handlers and
43 43 // is used to provide custom key handling. Its return value is used to determine
44 44 // if CodeMirror should ignore the event: true = ignore, false = don't ignore.
45 45 if (event.keyCode === 13 && event.shiftKey) {
46 46 // Always ignore shift-enter in CodeMirror as we handle it.
47 47 return true;
48 48 // } else if (event.keyCode == 32 && (event.ctrlKey || event.metaKey) && !event.altKey) {
49 49 } else if (event.keyCode == 9) {
50 50 var cur = editor.getCursor();
51 51 var pre_cursor = editor.getRange({line:cur.line,ch:0},cur).trim();
52 52 if (pre_cursor === "") {
53 53 // Don't autocomplete if the part of the line before the cursor is empty.
54 54 // In this case, let CodeMirror handle indentation.
55 55 return false;
56 56 } else {
57 57 // Autocomplete the current line.
58 58 event.stop();
59 59 var line = editor.getLine(cur.line);
60 60 this.is_completing = true;
61 61 this.completion_cursor = cur;
62 62 IPython.notebook.complete_cell(this, line, cur.ch);
63 63 return true;
64 64 }
65 65 } else {
66 66 if (this.is_completing && this.completion_cursor !== editor.getCursor()) {
67 67 this.is_completing = false;
68 68 this.completion_cursor = null;
69 69 }
70 70 return false;
71 71 };
72 72 };
73 73
74 74
75 75 CodeCell.prototype.finish_completing = function (matched_text, matches) {
76 76 if (!this.is_completing || matches.length === 0) {return;}
77 77 // console.log("Got matches", matched_text, matches);
78 78
79 79 var that = this;
80 80 var cur = this.completion_cursor;
81 81 var complete = $('<div/>').addClass('completions');
82 82 var select = $('<select/>').attr('multiple','true');
83 83 for (var i=0; i<matches.length; ++i) {
84 84 select.append($('<option/>').text(matches[i]));
85 85 }
86 86 select.children().first().attr('selected','true');
87 87 select.attr('size',Math.min(10,matches.length));
88 88 var pos = this.code_mirror.cursorCoords();
89 89 complete.css('left',pos.x+'px');
90 90 complete.css('top',pos.yBot+'px');
91 91 complete.append(select);
92 92
93 93 $('body').append(complete);
94 94 var done = false;
95 95
96 96 var insert = function (selected_text) {
97 97 that.code_mirror.replaceRange(
98 98 selected_text,
99 99 {line: cur.line, ch: (cur.ch-matched_text.length)},
100 100 {line: cur.line, ch: cur.ch}
101 101 );
102 102 };
103 103
104 104 var close = function () {
105 105 if (done) return;
106 106 done = true;
107 107 complete.remove();
108 108 that.is_completing = false;
109 109 that.completion_cursor = null;
110 110 };
111 111
112 112 var pick = function () {
113 113 insert(select.val()[0]);
114 114 close();
115 115 setTimeout(function(){that.code_mirror.focus();}, 50);
116 116 };
117 117
118 118 select.blur(close);
119 119 select.keydown(function (event) {
120 120 var code = event.which;
121 121 if (code === 13 || code === 32) {
122 122 // Pressing SPACE or ENTER will cause a pick
123 123 event.stopPropagation();
124 124 event.preventDefault();
125 125 pick();
126 126 } else if (code === 38 || code === 40) {
127 127 // We don't want the document keydown handler to handle UP/DOWN,
128 128 // but we want the default action.
129 129 event.stopPropagation();
130 130 } else {
131 131 // All other key presses simple exit completion.
132 132 event.stopPropagation();
133 133 event.preventDefault();
134 134 close();
135 135 that.code_mirror.focus();
136 136 }
137 137 });
138 138 // Double click also causes a pick.
139 139 select.dblclick(pick);
140 140 select.focus();
141 141 };
142 142
143 143
144 144 CodeCell.prototype.select = function () {
145 145 IPython.Cell.prototype.select.apply(this);
146 146 this.code_mirror.focus();
147 147 };
148 148
149 149
150 150 CodeCell.prototype.append_pyout = function (data, n) {
151 151 var toinsert = $("<div/>").addClass("output_area output_pyout hbox");
152 152 toinsert.append($('<div/>').
153 153 addClass('prompt output_prompt').
154 154 html('Out[' + n + ']:')
155 155 );
156 156 this.append_display_data(data, toinsert);
157 157 toinsert.children().last().addClass("box_flex1");
158 158 this.element.find("div.output").append(toinsert);
159 159 // If we just output latex, typeset it.
160 160 if (data["text/latex"] !== undefined) {
161 161 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
162 162 };
163 163 };
164 164
165 165
166 166 CodeCell.prototype.append_pyerr = function (ename, evalue, tb) {
167 167 var s = '';
168 168 var len = tb.length;
169 169 for (var i=0; i<len; i++) {
170 170 s = s + tb[i] + '\n';
171 171 }
172 172 s = s + '\n';
173 173 this.append_stream(s);
174 174 };
175 175
176 176
177 177 CodeCell.prototype.append_display_data = function (data, element) {
178 if (data["text/latex"] !== undefined) {
178 if (data["text/html"] !== undefined) {
179 this.append_html(data["text/html"], element);
180 } else if (data["text/latex"] !== undefined) {
179 181 this.append_latex(data["text/latex"], element);
180 182 // If it is undefined, then we just appended to div.output, which
181 183 // makes the latex visible and we can typeset it. The typesetting
182 184 // has to be done after the latex is on the page.
183 185 if (element === undefined) {
184 186 MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
185 187 };
186 188 } else if (data["image/svg+xml"] !== undefined) {
187 189 this.append_svg(data["image/svg+xml"], element);
188 190 } else if (data["image/png"] !== undefined) {
189 191 this.append_png(data["image/png"], element);
190 192 } else if (data["text/plain"] !== undefined) {
191 193 this.append_stream(data["text/plain"], element);
192 194 };
193 195 return element;
194 196 };
195 197
196 198
199 CodeCell.prototype.append_html = function (html, element) {
200 element = element || this.element.find("div.output");
201 var toinsert = $("<div/>").addClass("output_area output_html");
202 toinsert.append(html);
203 element.append(toinsert);
204 return element;
205 }
206
207
197 208 CodeCell.prototype.append_stream = function (data, element) {
198 209 element = element || this.element.find("div.output");
199 210 var toinsert = $("<div/>").addClass("output_area output_stream");
200 211 toinsert.append($("<pre/>").html(utils.fixConsole(data)));
201 212 element.append(toinsert);
202 213 return element;
203 214 };
204 215
205 216
206 217 CodeCell.prototype.append_svg = function (svg, element) {
207 218 element = element || this.element.find("div.output");
208 219 var toinsert = $("<div/>").addClass("output_area output_svg");
209 220 toinsert.append(svg);
210 221 element.append(toinsert);
211 222 return element;
212 223 };
213 224
214 225
215 226 CodeCell.prototype.append_png = function (png, element) {
216 227 element = element || this.element.find("div.output");
217 228 var toinsert = $("<div/>").addClass("output_area output_png");
218 229 toinsert.append($("<img/>").attr('src','data:image/png;base64,'+png));
219 230 element.append(toinsert);
220 231 return element;
221 232 };
222 233
223 234
224 235 CodeCell.prototype.append_latex = function (latex, element) {
225 236 // This method cannot do the typesetting because the latex first has to
226 237 // be on the page.
227 238 element = element || this.element.find("div.output");
228 239 var toinsert = $("<div/>").addClass("output_area output_latex");
229 240 toinsert.append(latex);
230 241 element.append(toinsert);
231 242 return element;
232 243 }
233 244
234 245
235 246 CodeCell.prototype.clear_output = function () {
236 247 this.element.find("div.output").html("");
237 248 };
238 249
239 250
240 251 CodeCell.prototype.clear_input = function () {
241 252 this.code_mirror.setValue('');
242 253 };
243 254
244 255
245 256 CodeCell.prototype.collapse = function () {
246 257 this.element.find('div.output').hide();
247 258 };
248 259
249 260
250 261 CodeCell.prototype.expand = function () {
251 262 this.element.find('div.output').show();
252 263 };
253 264
254 265
255 266 CodeCell.prototype.set_input_prompt = function (number) {
256 267 var n = number || ' ';
257 268 this.input_prompt_number = n
258 269 this.element.find('div.input_prompt').html('In&nbsp;[' + n + ']:');
259 270 };
260 271
261 272
262 273 CodeCell.prototype.get_code = function () {
263 274 return this.code_mirror.getValue();
264 275 };
265 276
266 277
267 278 CodeCell.prototype.set_code = function (code) {
268 279 return this.code_mirror.setValue(code);
269 280 };
270 281
271 282
272 283 CodeCell.prototype.at_top = function () {
273 284 var cursor = this.code_mirror.getCursor();
274 285 if (cursor.line === 0) {
275 286 return true;
276 287 } else {
277 288 return false;
278 289 }
279 290 };
280 291
281 292
282 293 CodeCell.prototype.at_bottom = function () {
283 294 var cursor = this.code_mirror.getCursor();
284 295 if (cursor.line === (this.code_mirror.lineCount()-1)) {
285 296 return true;
286 297 } else {
287 298 return false;
288 299 }
289 300 };
290 301
291 302
292 303 CodeCell.prototype.fromJSON = function (data) {
293 304 if (data.cell_type === 'code') {
294 305 this.set_code(data.code);
295 306 this.set_input_prompt(data.prompt_number);
296 307 };
297 308 };
298 309
299 310
300 311 CodeCell.prototype.toJSON = function () {
301 312 return {
302 313 code : this.get_code(),
303 314 cell_type : 'code',
304 315 prompt_number : this.input_prompt_number
305 316 };
306 317 };
307 318
308 319 IPython.CodeCell = CodeCell;
309 320
310 321 return IPython;
311 322 }(IPython));
312 323
General Comments 0
You need to be logged in to leave comments. Login now