Как (может) я использую файл custom.js под ноутбуком Jupyter?

В ноутбуке IPython (например, v3.1) я могу добавить файл ~/.ipython/profile_default/static/custom/custom.js для выполнения некоторых пользовательских JavaScript. Например, я мог бы сделать что-то вроде этого:

require(['base/js/namespace', 'base/js/events'], function(IPython, events) {
    console.log("A");
    events.on('app_initialized.NotebookApp', function() {
        console.log("B");
    });
    console.log("C");
});

Затем в консоли JS я увижу A, а затем B, а затем C.

Теперь, начиная с версии 4.0, они разделили его на ноутбук Jupyter. Тот же файл загружается (несмотря на то, что он находится под ~/.ipython, а не под ~/.jupyter), и код запускается. Однако я больше не вижу строку B. Я думаю, что приложение не инициализируется. Я все еще вижу, что он запускается в исходный код, но это происходит позже или просто не работает?

Как мне заставить работу снова работать? Мне больше не нужно ждать app_initialized? Является ли какое-либо из этих документов где-то?

Изменить

Эта страница, похоже, предполагает, что способ сделать это в наши дни - создать пользовательское расширение и поместить все действия в load_ipython_extension функция. Это правильно? Если да, то как насчет mathjax? И опции CodeMirror?

Ответы

Ответ 1

Как мне заставить работу снова работать? Мне просто не нужно ждать app_initialized больше?

У меня нет глубокого понимания рекомендуемого способа сделать это, но с Jupyter/IPython 4.0, ожидающим "notebook_loaded.Notebook" вместо "app_initialized.NotebookApp". используйте эту строку:

    events.on("notebook_loaded.Notebook", function () {

Ответ 2

Использование custom.js по-прежнему работает для меня, но похоже, что он перемещается по справедливому биту.

В настоящее время (версия 4.2.3), а также в документации для предстоящей версии 5.0, она находится в ~/.jupyter/custom/custom.js. См. Документацию на http://jupyter-notebook.readthedocs.io/en/latest/examples/Notebook/JavaScript%20Notebook%20Extensions.html#custom.js

Вы можете показать путь и содержимое custom.js, выполнив этот фрагмент в записной книжке:

from jupyter_core.paths import jupyter_config_dir
jupyter_dir = jupyter_config_dir()
import os.path
custom_js_path = os.path.join(jupyter_dir, 'custom', 'custom.js')
print("searching for custom.js in ", custom_js_path)
#  my custom js
if os.path.isfile(custom_js_path):
    with open(custom_js_path) as f:
        print(f.read())
else:
    print("You don't have a custom.js file")

Ответ 3

Этот вопрос возник из-за трекера Github - Проблемы с jupyter 4.0 - и ссылки на недавнее обновление, которое, как представляется, упрощает загрузку расширения: обновление кода:

"Отредактировав notebook.json вручную. По умолчанию он находится в ~/.jupyter/nbconfig/notebook.json:"

{
    "load_extensions": {
      "notify": true,
      "theme_toggle": true
  }
}

Добавление таких вещей, как "code_folding/main": true, также работает.

Итак, я понимаю, что это заменит использование custom.js для загрузки расширений?

Ответ 4

Событие app_initialized.NotebookApp все еще запущено, если вы посмотрите на блокнот static/notebook/js/main.js.

но вы должны прослушивать это событие, используя функцию define() из requireJS:

define([
  'base/js/namespace',
  'base/js/events'
], function(IPython, events) {
   events.on('app_initialized.NotebookApp', function() {
     // Your Code
   });
});

Здесь будет выполнен ваш обратный вызов.

Если вы введете свой custom.js:

 require(['base/js/namespace', 'base/js/events'], function(IPython, events) {
     events.on('notebook_loaded.Notebook', function() {
        console.log('require & notebook_loaded.Notebook');
    });
     events.on('app_initialized.NotebookApp', function() {
        console.log('require & app_initialized.NotebookApp');
     });
 });

 define(['base/js/namespace', 'base/js/events'], function(IPython, events) {
     events.on('notebook_loaded.Notebook', function() {
        console.log('define & notebook_loaded.Notebook');
    });
     events.on('app_initialized.NotebookApp', function() {
         console.log('define & app_initialized.NotebookApp');
     });
 });

Результатом в консоли будет:

define() & app_initialized.NotebookApp
define() & notebook_loaded.Notebook
require() & notebook_loaded.Notebook

Я думаю, что с require() вы регистрируетесь на событие, которое уже произошло...

require() ожидает, что все зависимости и подмодули будут инциализированы... что может быть слишком поздно для события app_initialized.NotebookApp.