diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js index 3ff0ae5a5..926a14c6d 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/main.js @@ -2,26 +2,34 @@ // by minrk https://github.com/minrk/ipython_extensions // See the history of contributions in README.md - -//define(["require", "jquery", "base/js/namespace", 'services/config', -// 'base/js/utils', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, toc2) { - -define(["require", "jquery", "base/js/namespace", 'services/config', - 'base/js/utils', 'notebook/js/codecell', "nbextensions/toc2/toc2"], function(require, $, IPython, configmod, utils, codecell, toc2 ) { - - var Notebook = require('notebook/js/notebook').Notebook - "use strict"; - +define([ + 'require', + 'jquery', + 'base/js/namespace', + 'services/config', + 'base/js/utils', + 'notebook/js/codecell', + './toc2' +], function( + require, + $, + IPython, + configmod, + utils, + codecell, + toc2 +) { + "use strict"; + + // imports + var highlight_toc_item = toc2.highlight_toc_item; + var table_of_contents = toc2.table_of_contents; + var toggle_toc = toc2.toggle_toc; // ...........Parameters configuration...................... - // define default values for config parameters if they were not present in general settings (notebook.json) + // default values for system-wide configurable parameters var cfg={'threshold':4, - 'number_sections':true, - 'toc_cell':false, - 'toc_window_display':false, - "toc_section_display": "block", - 'sideBar':true, - 'navigate_menu':true, + 'navigate_menu':true, 'moveMenuLeft': true, 'widenNotebook': false, 'colors': { @@ -34,75 +42,74 @@ define(["require", "jquery", "base/js/namespace", 'services/config', 'navigate_num': '#000000', }, collapse_to_match_collapsible_headings: false, - skip_h1_title: false, } + // default values for per-notebook configurable parameters + var metadata_settings = { + nav_menu: {}, + number_sections: true, + sideBar: true, + skip_h1_title: false, + toc_cell: false, + toc_position: {}, + toc_section_display: 'block', + toc_window_display: false, + }; + // add per-notebook settings into global config object + $.extend(true, cfg, metadata_settings); //.....................global variables.... - - var liveNotebook = !(typeof IPython == "undefined") - var st={} st.rendering_toc_cell = false; - st.config_loaded = false; - st.extension_initialized=false; - - st.nbcontainer_marginleft = $('#notebook-container').css('margin-left') - st.nbcontainer_marginright = $('#notebook-container').css('margin-right') - st.nbcontainer_width = $('#notebook-container').css('width') st.oldTocHeight = undefined - st.cell_toc = undefined; st.toc_index=0; - - - function read_config(cfg, callback) { // read after nb is loaded - // create config object to load parameters - var base_url = utils.get_body_data("baseUrl"); - var initial_cfg = $.extend(true, {}, cfg); - var config = new configmod.ConfigSection('notebook', { base_url: base_url }); - config.loaded.then(function(){ + var read_config = function (cfg, callback) { + IPython.notebook.config.loaded.then(function () { // config may be specified at system level or at document level. // first, update defaults with config loaded from server - cfg = $.extend(true, cfg, config.data.toc2); + $.extend(true, cfg, IPython.notebook.config.data.toc2); + // ensure notebook metadata has toc object, cache old values + var md = IPython.notebook.metadata.toc || {}; + // reset notebook metadata to remove old values + IPython.notebook.metadata.toc = {}; // then update cfg with any found in current notebook metadata // and save in nb metadata (then can be modified per document) - cfg = IPython.notebook.metadata.toc = $.extend(true, cfg, - IPython.notebook.metadata.toc); - // excepted colors that are taken globally (if defined) - cfg.colors = $.extend(true, {}, initial_cfg.colors); - try - {cfg.colors = IPython.notebook.metadata.toc.colors = $.extend(true, cfg.colors, config.data.toc2.colors); } - catch(e) {} - // and moveMenuLeft, threshold, wideNotebook, collapse_to_match_collapsible_headings taken globally (if it exists, otherwise default) - cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = initial_cfg.moveMenuLeft; - cfg.threshold = IPython.notebook.metadata.toc.threshold = initial_cfg.threshold; - cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = initial_cfg.widenNotebook; - cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = initial_cfg.collapse_to_match_collapsible_headings - if (config.data.toc2) { - if (typeof config.data.toc2.moveMenuLeft !== "undefined") { - cfg.moveMenuLeft = IPython.notebook.metadata.toc.moveMenuLeft = config.data.toc2.moveMenuLeft; - } - if (typeof config.data.toc2.threshold !== "undefined") { - cfg.threshold = IPython.notebook.metadata.toc.threshold = config.data.toc2.threshold; - } - if (typeof config.data.toc2.widenNotebook !== "undefined") { - cfg.widenNotebook = IPython.notebook.metadata.toc.widenNotebook = config.data.toc2.widenNotebook; - } - if (typeof config.data.toc2.collapse_to_match_collapsible_headings !== "undefined") { - cfg.collapse_to_match_collapsible_headings = IPython.notebook.metadata.toc.collapse_to_match_collapsible_headings = config.data.toc2.collapse_to_match_collapsible_headings; - } - } - // create highlights style section in document - create_additional_css(); - // call callbacks - callback && callback(); - st.config_loaded = true; - }) - config.load(); + Object.keys(metadata_settings).forEach(function (key) { + cfg[key] = IPython.notebook.metadata.toc[key] = (md.hasOwnProperty(key) ? md : cfg)[key]; + }); + // create highlights style section in document + create_additional_css(); + // call callbacks + callback && callback(); + }); return cfg; - } + }; + // extra download as html with toc menu (needs IPython kernel) + function addSaveAsWithToc() { + if (IPython.notebook.metadata.kernelspec.language == 'python') { + if ($('#save_html_with_toc').length == 0) { + $('#save_checkpoint').after("
") + $('#save_html_with_toc') + .append($('').text('Save as HTML (with toc)').attr("href", "#")) + .on('click', function (evt) { + if (IPython.notebook.metadata.kernelspec.language == 'python') { + var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2"; + console.log('[toc2] running:', code); + IPython.notebook.kernel.execute(code); + } + else { + alert('Sorry; this only works with a IPython kernel'); + $('#save_html_with_toc').remove(); + } + }); + } + } + else { + $('#save_html_with_toc').remove() + } + } diff --git a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js index 966c41012..591c2e35c 100644 --- a/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js +++ b/src/jupyter_contrib_nbextensions/nbextensions/toc2/toc2.js @@ -1,21 +1,31 @@ -//--------------------------------------------------------------------- - -//......... utilitary functions............ - -var liveNotebook = !(typeof IPython == "undefined") -var events; -if (liveNotebook) { - events = require('base/js/events'); -} -else { - // in non-live notebook, there's no event structure, so we make our own - if (window.events === undefined) { - var Events = function () {}; - window.events = $([new Events()]); +(require.specified('base/js/namespace') ? define : function (deps, callback) { + // if here, the Jupyter namespace hasn't been specified to be loaded. + // This means that we're probably embedded in a page, so we need to make + // our definition with a specific module name + return define('nbextensions/toc2/toc2', deps, callback); +})(['jquery', 'require'], function ($, require) { + "use strict"; + + var IPython; + var events; + var liveNotebook = false; + try { + // this will work in a live notebook because nbextensions & custom.js + // are loaded by/after notebook.js, which requires base/js/namespace + IPython = require('base/js/namespace'); + events = require('base/js/events'); + liveNotebook = true; + } + catch (err) { + // log the error, just in case we *are* in a live notebook + console.log('[toc2] working in non-live notebook:', err); + // in non-live notebook, there's no event structure, so we make our own + if (window.events === undefined) { + var Events = function () {}; + window.events = $([new Events()]); + } + events = window.events; } - events = window.events; -} - function incr_lbl(ary, h_idx) { //increment heading label w/ h_idx (zero based) ary[h_idx]++; @@ -100,34 +110,6 @@ function highlight_toc_item(evt, data) { } } - - // extra download as html with toc menu (needs IPython kernel) - function addSaveAsWithToc() { - var saveAsWithToc = $('#save_html_with_toc').length == 0 - var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python" - if (IPythonKernel) { - if ($('#save_html_with_toc').length == 0) { - $('#save_checkpoint').after("") - $('#save_html_with_toc').append($('').text('Save as HTML (with toc)').attr("href", "#")) - $('#save_html_with_toc').click(function() { - var IPythonKernel = IPython.notebook.metadata.kernelspec.language == "python" - if (IPythonKernel) { - var code = "!jupyter nbconvert '" + IPython.notebook.notebook_name + "' --template toc2" - console.log(code) - IPython.notebook.kernel.execute(code) - } else { - alert("Sorry; this only works with a IPython kernel"); - $('#save_html_with_toc').remove(); - } - }) - } - } else { - if ($('#save_html_with_toc').length > 0) $('#save_html_with_toc').remove() - } - } - - - var create_navigate_menu = function(callback) { $('#kernel_menu').parent().after('') $('#Navigate').addClass('dropdown').append($('').attr('href', '#').attr('id', 'Navigate_sub')) @@ -640,8 +622,9 @@ var table_of_contents = function (cfg,st) { } - - if (cfg.toc_cell) { + // check for st.cell_toc because we may have a non-live notebook where + // metadata says to use cell_toc, but the actual cell's been removed + if (cfg.toc_cell && st.cell_toc) { st.rendering_toc_cell = true; st.cell_toc.set_text( cell_toc_text + @@ -695,3 +678,21 @@ var table_of_contents = function (cfg,st) { }); }; + + return { + highlight_toc_item: highlight_toc_item, + table_of_contents: table_of_contents, + toggle_toc: toggle_toc, + }; +}); +// export table_of_contents to global namespace for backwards compatibility +// Do export synchronously, so that it's defined as soon as this file is loaded +if (!require.specified('base/js/namespace')) { + window.table_of_contents = function (cfg, st) { + // use require to ensure the module is correctly loaded before the + // actual call is made + require(['nbextensions/toc2/toc2'], function (toc2) { + toc2.table_of_contents(cfg, st); + }); + }; +} diff --git a/src/jupyter_contrib_nbextensions/templates/toc2.tpl b/src/jupyter_contrib_nbextensions/templates/toc2.tpl index ca5b751e7..b66e89981 100644 --- a/src/jupyter_contrib_nbextensions/templates/toc2.tpl +++ b/src/jupyter_contrib_nbextensions/templates/toc2.tpl @@ -50,7 +50,9 @@ $( document ).ready(function(){ st.toc_index=0; // fire the main function with these parameters - table_of_contents(cfg,st); + require(['nbextensions/toc2/toc2'], function (toc2) { + toc2.table_of_contents(cfg, st); + }); });