Как (может) я использую файл 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
.