diff --git a/README.md b/README.md index fb162fb..30badd3 100644 --- a/README.md +++ b/README.md @@ -224,10 +224,14 @@ History: - [@jfbercher](https://github.com/jfbercher), august 14, 2016, first version. - [@jfbercher](https://github.com/jfbercher), august 19, 2016, second version, - introduced support for R and javascript. - - Change extension name from `yapf_ext` to `code_prettify` + - changed extension name from `yapf_ext` to `code_prettify` - [@jcb91](https://github.com/jcb91), december 2016 - made addition of toolbar button & hotkey configurable - reworked to avoid regex replacements for conversion to/from kernel string formats, in favour of json-string interchange - made kernel-specific prettifier calls configurable, allowing support for different prettifiers & arbitrary kernels + - improved documentation +- [@jfbercher](https://github.com/jfbercher), december 2016 + - added a configurable shortkey to reflow the whole notebook + - extracted most of the code to build a general library of functions, `kernel_exec_on_cell.js`, which can be used for all nbextensions which needs to exec some code (via the current kernel) on the text from cells. diff --git a/code_prettify.js b/code_prettify.js index 2a70978..ada5741 100755 --- a/code_prettify.js +++ b/code_prettify.js @@ -1,35 +1,27 @@ // Copyright (c) Jupyter-Contrib Team. // Distributed under the terms of the Modified BSD License. +// Authors: @jfbercher and @jcb91 define(function(require, exports, module) { 'use strict'; var $ = require('jquery'); var Jupyter = require('base/js/namespace'); - var events = require('base/js/events'); - var utils = require('base/js/utils'); - var ConfigSection = require('services/config').ConfigSection; - var CodeCell = require('notebook/js/codecell').CodeCell; + var kernel_exec_on_cell = require('nbextensions/code_prettify/kernel_exec_on_cell') var mod_name = 'code_prettify'; var mod_log_prefix = '[' + mod_name + ']'; - var mod_edit_shortcuts = {}; - var mod_cmd_shortcuts = {}; - var default_kernel_config = { - library: '', - prefix: '', - postfix: '', - replacements_json_to_kernel: [], - trim_formatted_text: true - }; // gives default settings var cfg = { add_toolbar_button: true, hotkey: 'Ctrl-L', - prettify_all_hotkey: 'Ctrl-Shift-L', + process_all_hotkey: 'Ctrl-Shift-L', register_hotkey: true, show_alerts_for_errors: true, + extension_name: 'code_prettify', + extension_label: 'Code prettify', + extension_icon: 'fa-legal' }; cfg.kernel_config_map = { // map of parameters for supported kernels @@ -54,199 +46,48 @@ define(function(require, exports, module) { // before it is parsed into an object cfg.kernel_config_map_json = JSON.stringify(cfg.kernel_config_map); - /** - * return a Promise which will resolve/reject based on the kernel message - * type. - * The returned promise will be - * - resolved if the message was not an error - * - rejected using the message's error text if msg.msg_type is "error" - */ - function convert_error_msg_to_broken_promise (msg) { - return new Promise(function (resolve, reject) { - if (msg.msg_type == 'error') { - return reject(mod_log_prefix + '\n Error: ' + msg.content.ename + '\n' + msg.content.evalue); - } - return resolve(msg); - }); - } + function assign_hotkeys_from_config(cfg) { - function get_kernel_config() { - var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase(); - var kernel_config = cfg.kernel_config_map[kernelLanguage]; - // true => deep - return $.extend(true, {}, default_kernel_config, kernel_config); - } + var cfg_code_prettify = cfg; + var mod_edit_shortcuts = {}; + var mod_cmd_shortcuts = {}; - function transform_json_string_to_kernel_string (str, kernel_config) { - for (var ii=0; ii msg.content.text - var formatted_text = String(JSON.parse(msg.content.text)); - if (kernel_config.trim_formatted_text) { - formatted_text = formatted_text.trim(); - } - return formatted_text; - } - )); - }}}, - {silent: false} - ); - }); - } - - function add_toolbar_button () { - if ($('#code_prettify_button').length < 1) { - Jupyter.toolbar.add_buttons_group([{ - 'label': 'Code prettify', - 'icon': 'fa-legal', - 'callback': function (evt) { autoformat_cells(); }, - 'id': 'code_prettify_button' - }]); - } - } - - function assign_hotkeys_from_config () { mod_edit_shortcuts[cfg.hotkey] = { help: "code prettify", help_index: 'yf', - handler: function (evt) { autoformat_cells(); }, + handler: function(evt) { + return kernel_exec_on_cell.autoformat_cells(cfg_code_prettify); + }, }; - mod_edit_shortcuts[cfg.prettify_all_hotkey] = { + + mod_edit_shortcuts[cfg.process_all_hotkey] = { help: "code prettify the whole notebook", help_index: 'yf', - handler: function (evt) { - var indices = []; var N = Jupyter.notebook.ncells(); - for (var i = 0; i <= N; i++) { - indices.push(i); - } - autoformat_cells(indices); }, + handler: function(evt) { + return function() { + var indices = []; + var N = Jupyter.notebook.ncells(); + for (var i = 0; i <= N; i++) { + indices.push(i); + } + kernel_exec_on_cell.autoformat_cells(cfg_code_prettify, indices); + } + }(), }; - mod_cmd_shortcuts[cfg.prettify_all_hotkey] = mod_edit_shortcuts[cfg.prettify_all_hotkey] - } - - function setup_for_new_kernel () { - var kernelLanguage = Jupyter.notebook.metadata.kernelspec.language.toLowerCase(); - var kernel_config = cfg.kernel_config_map[kernelLanguage]; - if (kernel_config === undefined) { - $('#code_prettify_button').remove(); - alert(mod_log_prefix + " Sorry, can't use kernel language " + kernelLanguage + ".\n" + - "Configurations are currently only defined for the following languages:\n" + - ', '.join(Object.keys(cfg.kernel_config_map)) + "\n" + - "See readme for more details."); - } else { - if (cfg.add_toolbar_button) { - add_toolbar_button(); - } - if (cfg.register_hotkey) { - Jupyter.keyboard_manager.edit_shortcuts.add_shortcuts(mod_edit_shortcuts); - Jupyter.keyboard_manager.command_shortcuts.add_shortcuts(mod_cmd_shortcuts); - } - Jupyter.notebook.kernel.execute( - kernel_config.library, - { iopub: { output: convert_error_msg_to_broken_promise } }, - { silent: false } - ); + mod_cmd_shortcuts[cfg.process_all_hotkey] = mod_edit_shortcuts[cfg.process_all_hotkey] + if (cfg.register_hotkey) { + Jupyter.keyboard_manager.edit_shortcuts.add_shortcuts(mod_edit_shortcuts); + Jupyter.keyboard_manager.command_shortcuts.add_shortcuts(mod_cmd_shortcuts); } } function load_notebook_extension () { - var base_url = utils.get_body_data("baseUrl"); - var conf_section = new ConfigSection('notebook', {base_url: base_url}); - // first, load config - conf_section.load() - // now update default config with that loaded from server - .then(function on_success (config_data) { - $.extend(true, cfg, config_data[mod_name]); - }, function on_error (err) { - console.warn(mod_log_prefix, 'error loading config:', err); - }) - // next parse json config values - .then(function on_success () { - var parsed_kernel_cfg = JSON.parse(cfg.kernel_config_map_json); - $.extend(cfg.kernel_config_map, parsed_kernel_cfg); - }) - // if we failed to parse the json values in the config - // using catch pattern, we attempt to continue anyway using defaults - .catch(function on_error (err) { - console.warn( - mod_log_prefix, 'error parsing config variable', - mod_name + '.kernel_config_map_json to a json object:', - err - ); - }) - // now do things which required the config to be loaded - .then(function on_success () { - assign_hotkeys_from_config(); // initialize hotkey - // kernel may already have been loaded before we get here, in which - // case we've missed the kernel_ready.Kernel event, so try this - if (typeof Jupyter.notebook.kernel !== "undefined" && Jupyter.notebook.kernel !== null) { - setup_for_new_kernel(); + console.log("Executing kernel_exec_on_cell load_ipython") + kernel_exec_on_cell.main(mod_name, mod_log_prefix, cfg); + //kernel_exec_on_cell. + assign_hotkeys_from_config(kernel_exec_on_cell.bigCfg['code_prettify']); } - // on kernel_ready.Kernel, a new kernel has been started - events.on("kernel_ready.Kernel", function(event, data) { - console.log(mod_log_prefix, 'restarting for new kernel_ready.Kernel event'); - setup_for_new_kernel(); - }); - }); - } - return { load_ipython_extension: load_notebook_extension }; diff --git a/code_prettify.yaml b/code_prettify.yaml index 04294f5..2401f96 100644 --- a/code_prettify.yaml +++ b/code_prettify.yaml @@ -17,7 +17,7 @@ Parameters: description: Hotkey to use to prettify the selected cell(s) input_type: hotkey default: 'Ctrl-L' -- name: code_prettify.prettify_all_hotkey +- name: code_prettify.process_all_hotkey description: Hotkey to use to prettify the whole notebook input_type: hotkey default: 'Ctrl-Shift-L' @@ -49,3 +49,15 @@ Parameters: "postfix": ")));" } } +- name: code_prettify.extension_name + description: extension name + input_type: text + default: 'code_prettify' +- name: code_prettify.extension_label + description: and icon label + input_type: text + default: 'Code prettify' +- name: code_prettify.extension_icon + description: as well as the awesome font name for the button icon + input_type: text + default: 'fa-legal' \ No newline at end of file