File size: 5,885 Bytes
fdaf774 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
// Restrict output in a codecell to a maximum length
define([
'base/js/namespace',
'notebook/js/outputarea',
'notebook/js/codecell',
], function(
Jupyter,
oa,
cc
) {
"use strict";
// define default values for config parameters
var params = {
// maximum number of characters the output area is allowed to print
limit_output : 10000,
limit_stream : true,
limit_execute_result : true,
limit_display_data : false,
// message to print when output is limited
limit_output_message : '<b>limit_output extension: Maximum message size of {limit_output_length} exceeded with {output_length} characters</b>'
};
// to be called once config is loaded, this updates default config vals
// with the ones specified by the server's config file
var update_params = function() {
var config = Jupyter.notebook.config;
for (var key in params) {
if (config.data.hasOwnProperty(key) ){
params[key] = config.data[key];
}
}
};
function is_finite_number (n) {
n = parseFloat(n);
return !isNaN(n) && isFinite(n);
}
var initialize = function () {
update_params();
// sometimes limit_output metadata val can get stored as a string
params.limit_output = parseFloat(params.limit_output);
var old_handle_output = oa.OutputArea.prototype.handle_output;
oa.OutputArea.prototype.handle_output = function (msg) {
var handled_msg_types = ['stream', 'execute_result', 'display_data'];
if (handled_msg_types.indexOf(msg.header.msg_type) < 0) {
return old_handle_output.apply(this, arguments);
}
else {
// get MAX_CHARACTERS from cell metadata if present, otherwise param
//msg.header.msg_type
var MAX_CHARACTERS = params.limit_output;
var cell_metadata = this.element.closest('.cell').data('cell').metadata;
if (is_finite_number(cell_metadata.limit_output)) {
MAX_CHARACTERS = parseFloat(cell_metadata.limit_output);
}
// read the length of already-appended outputs from our data
var count = this.element.data('limit_output_count') || 0;
// update count with the length of this message
var old_count = count;
if (msg.header.msg_type === "stream" && params.limit_stream) {
count += String(msg.content.text).length;
}
else {
if ((msg.header.msg_type === "execute_result" && params.limit_execute_result) ||
(msg.header.msg_type === "display_data" && params.limit_display_data)) {
count += Math.max(
(msg.content.data['text/plain'] === undefined) ? 0 : String(msg.content.data['text/plain']).length,
(msg.content.data['text/html'] === undefined) ? 0 : String(msg.content.data['text/html']).length
);
}
}
// save updated count
this.element.data('limit_output_count', count);
if (count <= MAX_CHARACTERS) {
return old_handle_output.apply(this, arguments);
}
// if here, we'd exceed MAX_CHARACTERS with addition of this message.
if (old_count <= MAX_CHARACTERS) {
// Apply truncated portion of this message
var to_add = MAX_CHARACTERS - old_count;
if (msg.header.msg_type === "stream") {
msg.content.text = msg.content.text.substr(0, to_add);
}
else {
if (msg.content.data['text/plain'] !== undefined) {
msg.content.data['text/plain'] = msg.content.data['text/plain'].substr(0, to_add);
}
if (msg.content.data['text/html'] !== undefined) {
msg.content.data['text/html'] = msg.content.data['text/html'].substr(0, to_add);
}
}
old_handle_output.apply(this, arguments);
// display limit notification messages
console.log(
"limit_output: Maximum message size of", MAX_CHARACTERS,
"exceeded with", count, "characters. Further output muted."
);
// allow simple substitutions for output length for quick debugging
var limitmsg = params.limit_output_message.replace("{message_type}", msg.header.msg_type)
.replace("{limit_output_length}", MAX_CHARACTERS)
.replace("{output_length}", count);
this.append_output({
"output_type": "display_data",
"metadata": {}, // included to avoid warning
"data": {"text/html": limitmsg}
});
}
}
};
var old_clear_output = oa.OutputArea.prototype.clear_output;
oa.OutputArea.prototype.clear_output = function () {
// reset counter on execution.
this.element.data('limit_output_count', 0);
return old_clear_output.apply(this, arguments);
};
};
var load_ipython_extension = function() {
return Jupyter.notebook.config.loaded.then(initialize);
};
return {
load_ipython_extension : load_ipython_extension
};
});
|