From 50edc3bb60b0b519d5d43060b0fc8a33f556b0fb Mon Sep 17 00:00:00 2001 From: mahendrapaipuri Date: Wed, 18 Oct 2023 10:36:18 +0200 Subject: [PATCH 01/18] refactor: Migrate to src-layout * Move jupytext module inside src in root * Create a new module jupytext_config with same behaviour as console script --- {jupytext => src/jupytext}/__init__.py | 0 {jupytext => src/jupytext}/__main__.py | 0 {jupytext => src/jupytext}/cell_metadata.py | 0 {jupytext => src/jupytext}/cell_reader.py | 0 {jupytext => src/jupytext}/cell_to_text.py | 0 {jupytext => src/jupytext}/cli.py | 0 {jupytext => src/jupytext}/combine.py | 0 {jupytext => src/jupytext}/compare.py | 0 {jupytext => src/jupytext}/config.py | 0 {jupytext => src/jupytext}/contentsmanager.py | 0 {jupytext => src/jupytext}/doxygen.py | 0 {jupytext => src/jupytext}/formats.py | 0 {jupytext => src/jupytext}/header.py | 0 {jupytext => src/jupytext}/jupytext.py | 0 {jupytext => src/jupytext}/jupytext_config.py | 0 {jupytext => src/jupytext}/kernels.py | 0 {jupytext => src/jupytext}/labconfig.py | 0 {jupytext => src/jupytext}/languages.py | 0 {jupytext => src/jupytext}/magics.py | 0 {jupytext => src/jupytext}/metadata_filter.py | 0 {jupytext => src/jupytext}/myst.py | 0 {jupytext => src/jupytext}/paired_paths.py | 0 {jupytext => src/jupytext}/pairs.py | 0 {jupytext => src/jupytext}/pandoc.py | 0 {jupytext => src/jupytext}/parse_version.py | 0 {jupytext => src/jupytext}/pep8.py | 0 {jupytext => src/jupytext}/quarto.py | 0 {jupytext => src/jupytext}/reraise.py | 0 {jupytext => src/jupytext}/stringparser.py | 0 {jupytext => src/jupytext}/version.py | 0 src/jupytext_config/__init__.py | 1 + src/jupytext_config/__main__.py | 13 +++++++++++++ 32 files changed, 14 insertions(+) rename {jupytext => src/jupytext}/__init__.py (100%) rename {jupytext => src/jupytext}/__main__.py (100%) rename {jupytext => src/jupytext}/cell_metadata.py (100%) rename {jupytext => src/jupytext}/cell_reader.py (100%) rename {jupytext => src/jupytext}/cell_to_text.py (100%) rename {jupytext => src/jupytext}/cli.py (100%) rename {jupytext => src/jupytext}/combine.py (100%) rename {jupytext => src/jupytext}/compare.py (100%) rename {jupytext => src/jupytext}/config.py (100%) rename {jupytext => src/jupytext}/contentsmanager.py (100%) rename {jupytext => src/jupytext}/doxygen.py (100%) rename {jupytext => src/jupytext}/formats.py (100%) rename {jupytext => src/jupytext}/header.py (100%) rename {jupytext => src/jupytext}/jupytext.py (100%) rename {jupytext => src/jupytext}/jupytext_config.py (100%) rename {jupytext => src/jupytext}/kernels.py (100%) rename {jupytext => src/jupytext}/labconfig.py (100%) rename {jupytext => src/jupytext}/languages.py (100%) rename {jupytext => src/jupytext}/magics.py (100%) rename {jupytext => src/jupytext}/metadata_filter.py (100%) rename {jupytext => src/jupytext}/myst.py (100%) rename {jupytext => src/jupytext}/paired_paths.py (100%) rename {jupytext => src/jupytext}/pairs.py (100%) rename {jupytext => src/jupytext}/pandoc.py (100%) rename {jupytext => src/jupytext}/parse_version.py (100%) rename {jupytext => src/jupytext}/pep8.py (100%) rename {jupytext => src/jupytext}/quarto.py (100%) rename {jupytext => src/jupytext}/reraise.py (100%) rename {jupytext => src/jupytext}/stringparser.py (100%) rename {jupytext => src/jupytext}/version.py (100%) create mode 100644 src/jupytext_config/__init__.py create mode 100644 src/jupytext_config/__main__.py diff --git a/jupytext/__init__.py b/src/jupytext/__init__.py similarity index 100% rename from jupytext/__init__.py rename to src/jupytext/__init__.py diff --git a/jupytext/__main__.py b/src/jupytext/__main__.py similarity index 100% rename from jupytext/__main__.py rename to src/jupytext/__main__.py diff --git a/jupytext/cell_metadata.py b/src/jupytext/cell_metadata.py similarity index 100% rename from jupytext/cell_metadata.py rename to src/jupytext/cell_metadata.py diff --git a/jupytext/cell_reader.py b/src/jupytext/cell_reader.py similarity index 100% rename from jupytext/cell_reader.py rename to src/jupytext/cell_reader.py diff --git a/jupytext/cell_to_text.py b/src/jupytext/cell_to_text.py similarity index 100% rename from jupytext/cell_to_text.py rename to src/jupytext/cell_to_text.py diff --git a/jupytext/cli.py b/src/jupytext/cli.py similarity index 100% rename from jupytext/cli.py rename to src/jupytext/cli.py diff --git a/jupytext/combine.py b/src/jupytext/combine.py similarity index 100% rename from jupytext/combine.py rename to src/jupytext/combine.py diff --git a/jupytext/compare.py b/src/jupytext/compare.py similarity index 100% rename from jupytext/compare.py rename to src/jupytext/compare.py diff --git a/jupytext/config.py b/src/jupytext/config.py similarity index 100% rename from jupytext/config.py rename to src/jupytext/config.py diff --git a/jupytext/contentsmanager.py b/src/jupytext/contentsmanager.py similarity index 100% rename from jupytext/contentsmanager.py rename to src/jupytext/contentsmanager.py diff --git a/jupytext/doxygen.py b/src/jupytext/doxygen.py similarity index 100% rename from jupytext/doxygen.py rename to src/jupytext/doxygen.py diff --git a/jupytext/formats.py b/src/jupytext/formats.py similarity index 100% rename from jupytext/formats.py rename to src/jupytext/formats.py diff --git a/jupytext/header.py b/src/jupytext/header.py similarity index 100% rename from jupytext/header.py rename to src/jupytext/header.py diff --git a/jupytext/jupytext.py b/src/jupytext/jupytext.py similarity index 100% rename from jupytext/jupytext.py rename to src/jupytext/jupytext.py diff --git a/jupytext/jupytext_config.py b/src/jupytext/jupytext_config.py similarity index 100% rename from jupytext/jupytext_config.py rename to src/jupytext/jupytext_config.py diff --git a/jupytext/kernels.py b/src/jupytext/kernels.py similarity index 100% rename from jupytext/kernels.py rename to src/jupytext/kernels.py diff --git a/jupytext/labconfig.py b/src/jupytext/labconfig.py similarity index 100% rename from jupytext/labconfig.py rename to src/jupytext/labconfig.py diff --git a/jupytext/languages.py b/src/jupytext/languages.py similarity index 100% rename from jupytext/languages.py rename to src/jupytext/languages.py diff --git a/jupytext/magics.py b/src/jupytext/magics.py similarity index 100% rename from jupytext/magics.py rename to src/jupytext/magics.py diff --git a/jupytext/metadata_filter.py b/src/jupytext/metadata_filter.py similarity index 100% rename from jupytext/metadata_filter.py rename to src/jupytext/metadata_filter.py diff --git a/jupytext/myst.py b/src/jupytext/myst.py similarity index 100% rename from jupytext/myst.py rename to src/jupytext/myst.py diff --git a/jupytext/paired_paths.py b/src/jupytext/paired_paths.py similarity index 100% rename from jupytext/paired_paths.py rename to src/jupytext/paired_paths.py diff --git a/jupytext/pairs.py b/src/jupytext/pairs.py similarity index 100% rename from jupytext/pairs.py rename to src/jupytext/pairs.py diff --git a/jupytext/pandoc.py b/src/jupytext/pandoc.py similarity index 100% rename from jupytext/pandoc.py rename to src/jupytext/pandoc.py diff --git a/jupytext/parse_version.py b/src/jupytext/parse_version.py similarity index 100% rename from jupytext/parse_version.py rename to src/jupytext/parse_version.py diff --git a/jupytext/pep8.py b/src/jupytext/pep8.py similarity index 100% rename from jupytext/pep8.py rename to src/jupytext/pep8.py diff --git a/jupytext/quarto.py b/src/jupytext/quarto.py similarity index 100% rename from jupytext/quarto.py rename to src/jupytext/quarto.py diff --git a/jupytext/reraise.py b/src/jupytext/reraise.py similarity index 100% rename from jupytext/reraise.py rename to src/jupytext/reraise.py diff --git a/jupytext/stringparser.py b/src/jupytext/stringparser.py similarity index 100% rename from jupytext/stringparser.py rename to src/jupytext/stringparser.py diff --git a/jupytext/version.py b/src/jupytext/version.py similarity index 100% rename from jupytext/version.py rename to src/jupytext/version.py diff --git a/src/jupytext_config/__init__.py b/src/jupytext_config/__init__.py new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/src/jupytext_config/__init__.py @@ -0,0 +1 @@ + diff --git a/src/jupytext_config/__main__.py b/src/jupytext_config/__main__.py new file mode 100644 index 000000000..5220474ac --- /dev/null +++ b/src/jupytext_config/__main__.py @@ -0,0 +1,13 @@ +""" Main for Jupytext_config + +Call with (e.g.):: + + python -m jupytext_config list-default-viewer +""" + +import sys + +from jupytext.jupytext_config import main + +if __name__ == "__main__": + sys.exit(main()) From 4e823c7d6a76e2a1a6ac57df57390e99ac2699ed Mon Sep 17 00:00:00 2001 From: mahendrapaipuri Date: Wed, 18 Oct 2023 10:37:03 +0200 Subject: [PATCH 02/18] refactor: Remove legacy nb extension * Not relevant with Nb 7 --- jupytext/nbextension/README.md | 30 -- jupytext/nbextension/index.js | 434 ------------------------- jupytext/nbextension/jupytext.yml | 12 - jupytext/nbextension/jupytext_menu.png | Bin 101629 -> 0 bytes 4 files changed, 476 deletions(-) delete mode 100644 jupytext/nbextension/README.md delete mode 100644 jupytext/nbextension/index.js delete mode 100644 jupytext/nbextension/jupytext.yml delete mode 100644 jupytext/nbextension/jupytext_menu.png diff --git a/jupytext/nbextension/README.md b/jupytext/nbextension/README.md deleted file mode 100644 index 00fda66ac..000000000 --- a/jupytext/nbextension/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# A Jupyter notebook extension for Jupytext - -This extension adds a [Jupytext](https://github.com/mwouts/jupytext/blob/main/README.md) menu to Jupyter notebook. Use the menu to select the desired ipynb/text pairing for your notebook. - -![Jupytext menu screenshot](jupytext_menu.png) - -## Installation - -The extension requires [Jupytext](https://github.com/mwouts/jupytext/blob/main/README.md). Please make sure that Jupytext is installed on you system, and that its contents manager is active, i.e. that Markdown files and scripts are displayed with a notebook icon. - -Installing Jupytext activates the Jupytext Menu by default. If you want to install and activate it manually, use the following commands: - -```bash -jupyter nbextension install --py jupytext -jupyter nbextension enable --py jupytext -``` - -Add `--user` to these commands if you want to activate the extension only for the current user. - -## How to develop this extension - -If you wish to develop this extension, install the javascript file locally with: - -```bash -cd jupytext/nbextension -jupyter nbextension install index.js --symlink --user -jupyter nbextension enable index --user -``` - -Then, make the desired changes to `index.js` and reload the extension by simply refreshing the notebook (Ctrl+R). In case your OS does not allow symlinks, edit the copy of `index.js` that is actually used by Jupyter (refer to the output of `jupyter nbextension install --user index.js`). diff --git a/jupytext/nbextension/index.js b/jupytext/nbextension/index.js deleted file mode 100644 index 692b246da..000000000 --- a/jupytext/nbextension/index.js +++ /dev/null @@ -1,434 +0,0 @@ -// A Jupyter notebook extension for Jupytext -// Refer to the documentation at -// https://github.com/mwouts/jupytext/blob/main/jupytext/nbextension/README.md - -// The most convenient way to edit this file is to edit the version installed by pip at -// share/jupyter/nbextensions/jupytext - -define([ - 'jquery', - 'base/js/namespace', - 'base/js/dialog', - 'base/js/events', - 'base/js/utils', -], function ( - $, - Jupyter, - dialog, - events, - utils -) { - "use strict"; - - function getSelectedJupytextFormats() { - var str_formats = Jupyter.notebook.metadata.jupytext && Jupyter.notebook.metadata.jupytext.formats ? Jupyter.notebook.metadata.jupytext.formats : ''; - var unfiltered_formats = str_formats.split(','); - var formats = []; - for (var i in unfiltered_formats) { - var fmt = unfiltered_formats[i]; - if (fmt) - formats.push(fmt); - } - - if (Jupyter.notebook.metadata.language_info) { - var script_ext = Jupyter.notebook.metadata.language_info.file_extension.substring(1); - formats = formats.map(function (fmt) { - if (fmt === script_ext) - return 'auto:light'; - return fmt.replace(script_ext + ':', 'auto:'); - }); - } - - var notebook_extension = Jupyter.notebook.notebook_path.split('.').pop(); - notebook_extension = ['ipynb', 'md', 'Rmd', 'qmd'].indexOf(notebook_extension) == -1 ? 'auto' : notebook_extension; - for (var i in formats) { - var ext = formats[i].split(':')[0]; - if (ext == notebook_extension) - return formats; - } - - // the notebook extension was not found among the formats - if (['ipynb', 'md', 'Rmd', 'qmd'].indexOf(notebook_extension) != -1) - formats.push(notebook_extension); - else { - var format_name = Jupyter.notebook.metadata.jupytext && Jupyter.notebook.metadata.jupytext.text_representation - && Jupyter.notebook.metadata.jupytext.text_representation.format_name ? - Jupyter.notebook.metadata.jupytext.text_representation.format_name : 'light'; - formats.push('auto:' + format_name); - } - return formats; - } - - function checkSelectedJupytextFormats() { - - var formats = getSelectedJupytextFormats(); - console.log('Jupytext.formats=' + formats.join()); - - $('[id^=jupytext_pair_]' + '>.fa').toggleClass('fa-check', false); - for (var i in formats) { - var fmt = formats[i]; - $('#jupytext_pair_' + fmt.replace(':', '_') + ' > .fa').toggleClass('fa-check', true); - - // any custom format? - if (['ipynb', 'auto:light', 'auto:percent', 'auto:hydrogen', 'auto:nomarker', 'md', 'Rmd', 'qmd', 'md:myst'].indexOf(fmt) == -1) - $('#jupytext_pair_custom' + ' > .fa').toggleClass('fa-check', true); - } - - // just one format? - if (formats.length === 1) - $('#jupytext_pair_none').parent().addClass('disabled'); - else - $('#jupytext_pair_none').parent().removeClass('disabled'); - } - - function checkAutosave() { - console.log('Jupyter.notebook.autosave_interval=' + Jupyter.notebook.autosave_interval); - $('#autosave > .fa').toggleClass('fa-check', Jupyter.notebook.autosave_interval > 0); - } - - function checkIncludeMetadata() { - if (!Jupyter.notebook.metadata.jupytext || !Jupyter.notebook.metadata.jupytext.notebook_metadata_filter) { - $('#jupytext_metadata > .fa').toggleClass('fa-check', true); - $('#jupytext_metadata').parent().removeClass('disabled'); - return; - } - if (Jupyter.notebook.metadata.jupytext.notebook_metadata_filter === "-all") { - $('#jupytext_metadata > .fa').toggleClass('fa-check', false); - $('#jupytext_metadata').parent().removeClass('disabled'); - return; - } - // Custom metadata filter => we disable the option - $('#jupytext_metadata > .fa').toggleClass('fa-check', true); - $('#jupytext_metadata').parent().addClass('disabled'); - } - - function onClickedJupytextPair(data) { - if (!Jupyter.notebook.notebook_path) - return; - var format = $(this).data('format'); - if (format === 'custom') { - alert("Please use the notebook metadata editor for this (Menu: Edit/Edit Notebook Metadata)."); - return; - } - var formats = getSelectedJupytextFormats(); - var notebook_extension = Jupyter.notebook.notebook_path.split('.').pop(); - notebook_extension = ['ipynb', 'md', 'Rmd', 'qmd'].indexOf(notebook_extension) == -1 ? 'auto' : notebook_extension; - - // Toggle the selected format - var index = formats.indexOf(format); - if (format === 'none') { - // Only keep one format - one that matches the current extension - for (var i in formats) { - var fmt = formats[i]; - if (fmt.split(':')[0] === notebook_extension) { - formats = [fmt]; - break; - } - } - } - else if (index != -1) { - formats.splice(index, 1); - - // The current file extension can't be unpaired - var ext_found = false; - for (var i in formats) { - var fmt = formats[i]; - if (fmt.split(':')[0] === notebook_extension) { - ext_found = true; - break; - } - } - - if (!ext_found) - return; - } else { - // We can't have the same extension multiple times - var new_formats = []; - for (var i in formats) { - var fmt = formats[i]; - if (fmt.split(':')[0] !== format.split(':')[0]) { - new_formats.push(fmt) - } - } - - formats = new_formats; - formats.push(format); - } - - if (formats.length === 1) { - if (notebook_extension !== 'auto') - formats = []; - else { - if (Jupyter.notebook.metadata.jupytext && Jupyter.notebook.metadata.jupytext.text_representation) { - var format_name = formats[0].split(':')[1]; - Jupyter.notebook.metadata.jupytext.text_representation.format_name = format_name; - formats = []; - } - } - } - - if (formats.length === 0) { - if (!Jupyter.notebook.metadata.jupytext) - return; - if (Jupyter.notebook.metadata.jupytext.formats) - delete Jupyter.notebook.metadata.jupytext['formats']; - if (Object.keys(Jupyter.notebook.metadata.jupytext).length === 0) - delete Jupyter.notebook.metadata['jupytext']; - } else { - if (!Jupyter.notebook.metadata.jupytext) - Jupyter.notebook.metadata.jupytext = {}; - Jupyter.notebook.metadata.jupytext['formats'] = formats.join(); - } - - checkSelectedJupytextFormats(); - Jupyter.notebook.set_dirty(); - } - - function onToggleMetadata() { - if (!Jupyter.notebook.metadata.jupytext) { - Jupyter.notebook.metadata.jupytext = { - "notebook_metadata_filter": "-all", - "cell_metadata_filter": "-all" - }; - } else { - if (!Jupyter.notebook.metadata.jupytext.notebook_metadata_filter) { - Jupyter.notebook.metadata.jupytext.notebook_metadata_filter = "-all"; - if (!Jupyter.notebook.metadata.jupytext.cell_metadata_filter) - Jupyter.notebook.metadata.jupytext.cell_metadata_filter = "-all"; - } else { - delete Jupyter.notebook.metadata.jupytext['notebook_metadata_filter']; - if (Jupyter.notebook.metadata.jupytext.cell_metadata_filter === "-all") - delete Jupyter.notebook.metadata.jupytext['cell_metadata_filter']; - if (Object.keys(Jupyter.notebook.metadata.jupytext).length === 0) - delete Jupyter.notebook.metadata['jupytext']; - } - } - - checkIncludeMetadata(); - Jupyter.notebook.set_dirty(); - } - - function onToggleAutosave() { - Jupyter.notebook.autosave_interval = Jupyter.notebook.autosave_interval > 0 ? 0 : 120000; - checkAutosave(); - } - - function updateJupytextMenu() { - checkSelectedJupytextFormats(); - checkAutosave(); - checkIncludeMetadata(); - } - - function jupytext_pair(format, text, active) { - return $('
  • ') - .addClass(typeof active === 'undefined' || active ? null : 'disabled') - .append($('') - .attr('id', 'jupytext_pair_' + format.replace(':', '_')) - .text(text) - .attr('title', format === 'custom' ? 'Custom Jupytext configuration' : 'jupytext.format=' + format) - .data('format', format) - .css('width', '280px') - .attr('href', '#') - .on('click', onClickedJupytextPair) - .prepend($('').addClass('fa menu-icon pull-right')) - ); - } - - function new_text_notebook(ext = '.md') { - // Differences with KernelSelector.prototype.new_notebook from - // https://github.com/jupyter/notebook/blob/ - // 6e9256b0641a85baf664e846515085bac2c082a3/notebook/static/notebook/js/kernelselector.js - // - added ext argument - // - kernel_name is the currently selected one - // - "that" replaced with Jupyter - - var w = window.open('', IPython._target); - // Create a new notebook in the same path as the current - // notebook's path. - var parent = utils.url_path_split(Jupyter.notebook.notebook_path)[0]; - Jupyter.notebook.contents.new_untitled(parent, { type: "notebook", ext: ext }).then( - function (data) { - var url = utils.url_path_join( - Jupyter.notebook.base_url, 'notebooks', - utils.encode_uri_components(data.path) - ); - url += "?kernel_name=" + Jupyter.notebook.metadata.kernelspec.name; - w.location = url; - }, - function (error) { - w.close(); - dialog.modal({ - title: i18n.msg._('Creating Notebook Failed'), - body: i18n.msg.sprintf(i18n.msg._("The error was: %s"), error.message), - buttons: { 'OK': { 'class': 'btn-primary' } } - }); - } - ); - }; - - function text_notebook_entry(title, ext = null) { - const new_script_notebook_id = 'new_notebook_' + ext.replace('.', '').replace(':', '_'); - return $('
  • ') - .append($('') - .attr('id', new_script_notebook_id) - .text(title) - .attr('title', title) - .data('ext', ext) - .css('width', '280px') - .attr('href', '#') - .on('click', onClickedTextNotebook) - .prepend($('').addClass('fa menu-icon pull-right')) - ); - }; - - function onClickedTextNotebook(data) { - const ext = $(this).data('ext'); - if (ext) { new_text_notebook(ext); }; - }; - - function updateNewScriptNotebookMenu() { - var format_name; - for (format_name of ['light', 'percent', 'hydrogen', 'nomarker']) { - const new_script_notebook_menu = $('#new_notebook_auto_' + format_name); - if (Jupyter.notebook.metadata.language_info) { - var script_ext = Jupyter.notebook.metadata.language_info.file_extension + ':' + format_name; - var language_name = Jupyter.notebook.metadata.language_info.name; - language_name = language_name.charAt(0).toUpperCase() + language_name.slice(1); - var title = language_name + ' Script in ' + format_name + ' format'; - new_script_notebook_menu.parent().removeClass('disabled'); - new_script_notebook_menu.data('ext', script_ext); - new_script_notebook_menu.attr('title', title); - new_script_notebook_menu.text(title); - } else { - new_script_notebook_menu.parent().addClass('disabled'); - new_script_notebook_menu.data('ext', null); - } - ; - } - ; - }; - - var jupytext_menu = function () { - if ($('#jupytext_menu').length === 0) { - - var JupytextMenu = $('').attr('href', '#') - .addClass('dropdown-toogle') - .attr('data-toggle', 'dropdown') - .attr('aria-expanded', 'false') - .text('Jupytext') - .attr('title', 'Jupyter notebooks as Markdown documents, Julia, Python or R scripts') - .on('mouseover', updateJupytextMenu); - - var JupytextActions = $('