Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language specific text notebook #1163

Merged
merged 17 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,10 @@
"@jupyterlab/settingregistry": "^4.0.0",
"@jupyterlab/translation": "^4.0.0",
"@jupyterlab/ui-components": "^4.0.0",
"@lumino/commands": "^2.0.0",
"@lumino/coreutils": "^2.0.0",
"@lumino/disposable": "^2.0.0",
"buffer": "^6.0.3",
"jupyterlab-rise": "^0.41.0"
},
"devDependencies": {
Expand Down
212 changes: 42 additions & 170 deletions jupyterlab/packages/jupyterlab-jupytext-extension/schema/plugin.json
Original file line number Diff line number Diff line change
@@ -1,182 +1,54 @@
{
"title": "Jupytext",
"description": "Jupytext Menu Settings.",
"description": "List of Jupytext Text Notebook formats that will be added to launcher.\n\nWhen any of percent, light, hydrogen and nomarker formats is selected, all the available kernel variants will be added to launcher. For instance, if Python and R kernels are installed, percent format will add launcher items to create Python and R Text notebooks with percent format.\n\nRefresh the current browser tab for the changes to take effect.",
"properties": {
"auto:percent": {
"type": "boolean",
"title": "Text Notebook as Script in Percent Format",
"default": true
},
"auto:light": {
"type": "boolean",
"title": "Text Notebook as Script in Light Format",
"default": false
},
"auto:hydrogen": {
"type": "boolean",
"title": "Text Notebook as Script in Hydrogen Format",
"default": false
},
"auto:nomarker": {
"type": "boolean",
"title": "Text Notebook as Script in Nomarker Format",
"default": false
},
"md:myst": {
"type": "boolean",
"title": "MyST Markdown Notebook",
"default": true
},
"md": {
"type": "boolean",
"title": "Markdown Notebook",
"default": false
},
"Rmd": {
"type": "boolean",
"title": "R Markdown Notebook",
"default": false
},
"qmd": {
"type": "boolean",
"title": "Quarto Markdown Notebook",
"default": false
},
"category": {
"title": "Category",
"description": "Category under which Jupytext Text Notebooks will be placed. Refresh the current browser tab for the changes to take effect.",
"description": "Category under which Jupytext Text Notebooks will be placed.",
"type": "string",
"default": "Jupytext"
},
"format": {
"title": "Jupytext Text Notebook Launcher Items Formats",
"description": "List of Jupytext Text Notebook formats that will be added to launcher. Refresh the current browser tab for the changes to take effect.",
"items": {
"type": "string"
},
"type": "array",
"default": ["auto:light", "auto:percent", "md", "md:myst", "Rmd"]
}
},
"jupyter.lab.menus": {
"main": [
{
"id": "jp-mainmenu-jupytext-menu",
"label": "Jupytext",
"rank": 80,
"items": [
{
"type": "submenu",
"submenu": {
"id": "jp-mainmenu-jupytext-new",
"label": "New Text Notebook",
"items": [
{
"command": "jupytext:create-new-text-noteboook-auto:percent",
"rank": 1
},
{
"type": "separator",
"rank": 2
},
{
"command": "jupytext:create-new-text-noteboook-auto:light",
"rank": 5
},
{
"command": "jupytext:create-new-text-noteboook-auto:hydrogen",
"rank": 10
},
{
"command": "jupytext:create-new-text-noteboook-auto:nomarker",
"rank": 15
},
{
"type": "separator",
"rank": 16
},
{
"command": "jupytext:create-new-text-noteboook-md",
"rank": 20
},
{
"command": "jupytext:create-new-text-noteboook-md:myst",
"rank": 25
},
{
"type": "separator",
"rank": 26
},
{
"command": "jupytext:create-new-text-noteboook-Rmd",
"rank": 30
},
{
"command": "jupytext:create-new-text-noteboook-qmd",
"rank": 35
}
]
},
"rank": 1
},
{
"type": "submenu",
"submenu": {
"id": "jp-mainmenu-jupytext-new",
"label": "Pair Notebook",
"items": [
{
"command": "jupytext:ipynb",
"rank": 1
},
{
"type": "separator",
"rank": 2
},
{
"command": "jupytext:auto:light",
"rank": 5
},
{
"command": "jupytext:auto:percent",
"rank": 10
},
{
"command": "jupytext:auto:hydrogen",
"rank": 15
},
{
"command": "jupytext:auto:nomarker",
"rank": 20
},
{
"type": "separator",
"rank": 25
},
{
"command": "jupytext:md",
"rank": 30
},
{
"command": "jupytext:md:myst",
"rank": 35
},
{
"type": "separator",
"rank": 40
},
{
"command": "jupytext:Rmd",
"rank": 45
},
{
"command": "jupytext:qmd",
"rank": 50
},
{
"type": "separator",
"rank": 55
},
{
"command": "jupytext:custom",
"rank": 60
},
{
"type": "separator",
"rank": 65
},
{
"command": "jupytext:none",
"rank": 70
}
]
},
"rank": 10
},
{
"type": "separator",
"rank": 11
},
{
"command": "jupytext:metadata",
"rank": 30
},
{
"type": "separator",
"rank": 31
},
{
"command": "jupytext:faq",
"rank": 40
},
{
"command": "jupytext:reference",
"rank": 41
}
]
}
]
},
"additionalProperties": false,
"type": "object"
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,10 @@ import { TranslationBundle } from '@jupyterlab/translation';

import {
LANGUAGE_INDEPENDENT_NOTEBOOK_EXTENSIONS,
ALL_JUPYTEXT_FORMATS,
ALL_JUPYTEXT_FORMAT_EXTENSIONS,
IJupytextFormat,
JUPYTEXT_FORMATS,
IJupytextSection,
} from './tokens';

/**
* Get a list of all supported Jupytext formats
*/
export function getAvailJupytextFormats(
trans: TranslationBundle
): IJupytextFormat[] {
return ALL_JUPYTEXT_FORMATS.map((formatObj) => {
return { format: formatObj.format, label: trans.__(formatObj.label) };
});
}

/**
* Get Jupytext format of current widget if it is a text notebook
*/
Expand Down Expand Up @@ -137,8 +124,8 @@ export function isPairCommandToggled(
const selectedFormats = getSelectedFormats(notebookTracker);

if (format === 'custom') {
for (const selecFormat of selectedFormats) {
if (!ALL_JUPYTEXT_FORMAT_EXTENSIONS.includes(selecFormat)) {
for (const selectedFormat of selectedFormats) {
if (!JUPYTEXT_FORMATS.includes(selectedFormat)) {
return true;
}
}
Expand Down
101 changes: 101 additions & 0 deletions jupyterlab/packages/jupyterlab-jupytext-extension/src/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import {
IToolbarWidgetRegistry,
createToolbarFactory,
} from '@jupyterlab/apputils';

import {
INotebookTracker,
NotebookPanel,
NotebookWidgetFactory,
} from '@jupyterlab/notebook';

import { ISettingRegistry } from '@jupyterlab/settingregistry';

import { DocumentRegistry } from '@jupyterlab/docregistry';

import { IRenderMimeRegistry } from '@jupyterlab/rendermime';

import { IEditorServices } from '@jupyterlab/codeeditor';

import { ITranslator, TranslationBundle } from '@jupyterlab/translation';

import { IRisePreviewFactory } from 'jupyterlab-rise';

import { FACTORY, FILE_TYPES } from './tokens';

export function createFactory(
kernelFileTypeNames: string[],
toolbarRegistry: IToolbarWidgetRegistry,
settingRegistry: ISettingRegistry,
docRegistry: DocumentRegistry,
notebookTracker: INotebookTracker,
notebookFactory: NotebookWidgetFactory.IFactory,
contentFactory: NotebookPanel.IContentFactory,
editorServices: IEditorServices,
rendermime: IRenderMimeRegistry,
translator: ITranslator,
trans: TranslationBundle,
riseFactory: IRisePreviewFactory | null
) {
const allFileTypes = FILE_TYPES.concat(kernelFileTypeNames);
// primarily this block is copied/pasted from jlab4 code and specifically
// jupyterlab/packages/notebook-extension/src/index.ts
// inside the function `activateWidgetFactory` at line 1150 as of this writing
//
const toolbarFactory = createToolbarFactory(
toolbarRegistry,
settingRegistry,
'Notebook',
'@jupyterlab/notebook-extension:panel',
translator
);
// Duplicate notebook factory to apply it on Jupytext notebooks
// Mirror: https://github.com/jupyterlab/jupyterlab/blob/8a8c3752564f37493d4eb6b4c59008027fa83880/packages/notebook-extension/src/index.ts#L860
const factory = new NotebookWidgetFactory({
name: FACTORY,
label: trans.__(FACTORY),
fileTypes: allFileTypes,
modelName: notebookFactory.modelName ?? 'notebook',
preferKernel: notebookFactory.preferKernel ?? true,
canStartKernel: notebookFactory.canStartKernel ?? true,
rendermime,
contentFactory,
editorConfig: notebookFactory.editorConfig,
notebookConfig: notebookFactory.notebookConfig,
mimeTypeService: editorServices.mimeTypeService,
toolbarFactory: toolbarFactory,
translator,
});
docRegistry.addWidgetFactory(factory);

// Register widget created with the new factory in the notebook tracker
// This is required to activate notebook commands (and therefore shortcuts)
let id = 0; // The ID counter for notebook panels.
const ft = docRegistry.getFileType('notebook');

factory.widgetCreated.connect((sender, widget) => {
// If the notebook panel does not have an ID, assign it one.
widget.id = widget.id || `notebook-jupytext-${++id}`;

// Set up the title icon
widget.title.icon = ft?.icon;
widget.title.iconClass = ft?.iconClass ?? '';
widget.title.iconLabel = ft?.iconLabel ?? '';

// Notify the widget tracker if restore data needs to update.
widget.context.pathChanged.connect(() => {
// @ts-expect-error Trick using private API
void notebookTracker.save(widget);
});
// Add the notebook panel to the tracker.
// @ts-expect-error Trick using private API
void notebookTracker.add(widget);
});

// Add support for RISE slides
if (riseFactory) {
for (const fileType of allFileTypes) {
riseFactory.addFileType(fileType);
}
}
}
Loading
Loading