|
@@ -57,7 +57,7 @@ import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
|
|
|
|
import { ServiceManager } from '@jupyterlab/services';
|
|
|
|
|
|
-import { ReadonlyJSONObject } from '@phosphor/coreutils';
|
|
|
+import { ReadonlyJSONObject, JSONValue } from '@phosphor/coreutils';
|
|
|
|
|
|
import { Message, MessageLoop } from '@phosphor/messaging';
|
|
|
|
|
@@ -212,17 +212,29 @@ const FACTORY = 'Notebook';
|
|
|
const CELL_TOOLS_RANK = 400;
|
|
|
|
|
|
/**
|
|
|
- * The allowed Export To ... formats and their human readable labels.
|
|
|
+ * The exluded Export To ...
|
|
|
+ * (returned from nbconvert's export list)
|
|
|
*/
|
|
|
-const EXPORT_TO_FORMATS = [
|
|
|
- { format: 'html', label: 'HTML' },
|
|
|
- { format: 'latex', label: 'LaTeX' },
|
|
|
- { format: 'markdown', label: 'Markdown' },
|
|
|
- { format: 'pdf', label: 'PDF' },
|
|
|
- { format: 'rst', label: 'ReStructured Text' },
|
|
|
- { format: 'script', label: 'Executable Script' },
|
|
|
- { format: 'slides', label: 'Reveal.js Slides' }
|
|
|
-];
|
|
|
+const FORMAT_EXCLUDE = ['notebook', 'python', 'custom'];
|
|
|
+
|
|
|
+/**
|
|
|
+ * The exluded Cell Inspector Raw NbConvert Formats
|
|
|
+ * (returned from nbconvert's export list)
|
|
|
+ */
|
|
|
+const RAW_FORMAT_EXCLUDE = ['pdf', 'slides', 'script', 'notebook', 'custom'];
|
|
|
+
|
|
|
+/**
|
|
|
+ * The default Export To ... formats and their human readable labels.
|
|
|
+ */
|
|
|
+const FORMAT_LABEL: { [k: string]: string } = {
|
|
|
+ html: 'HTML',
|
|
|
+ latex: 'LaTeX',
|
|
|
+ markdown: 'Markdown',
|
|
|
+ pdf: 'PDF',
|
|
|
+ rst: 'ReStructured Text',
|
|
|
+ script: 'Executable Script',
|
|
|
+ slides: 'Reveal.js Slides'
|
|
|
+};
|
|
|
|
|
|
/**
|
|
|
* The notebook widget tracker provider.
|
|
@@ -288,9 +300,9 @@ function activateCellTools(
|
|
|
const celltools = new CellTools({ tracker });
|
|
|
const activeCellTool = new CellTools.ActiveCellTool();
|
|
|
const slideShow = CellTools.createSlideShowSelector();
|
|
|
- const nbConvert = CellTools.createNBConvertSelector();
|
|
|
const editorFactory = editorServices.factoryService.newInlineEditor;
|
|
|
const metadataEditor = new CellTools.MetadataEditorTool({ editorFactory });
|
|
|
+ const services = app.serviceManager;
|
|
|
|
|
|
// Create message hook for triggers to save to the database.
|
|
|
const hook = (sender: any, message: Message): boolean => {
|
|
@@ -307,13 +319,29 @@ function activateCellTools(
|
|
|
}
|
|
|
return true;
|
|
|
};
|
|
|
-
|
|
|
+ let optionsMap: { [key: string]: JSONValue } = {};
|
|
|
+ optionsMap.None = '-';
|
|
|
+ services.nbconvert.getExportFormats().then(response => {
|
|
|
+ if (response) {
|
|
|
+ // convert exportList to palette and menu items
|
|
|
+ const formatList = Object.keys(response);
|
|
|
+ formatList.forEach(function(key) {
|
|
|
+ if (RAW_FORMAT_EXCLUDE.indexOf(key) === -1) {
|
|
|
+ let capCaseKey = key[0].toUpperCase() + key.substr(1);
|
|
|
+ let labelStr = FORMAT_LABEL[key] ? FORMAT_LABEL[key] : capCaseKey;
|
|
|
+ let mimeType = response[key].output_mimetype;
|
|
|
+ optionsMap[labelStr] = mimeType;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const nbConvert = CellTools.createNBConvertSelector(optionsMap);
|
|
|
+ celltools.addItem({ tool: nbConvert, rank: 3 });
|
|
|
+ }
|
|
|
+ });
|
|
|
celltools.title.iconClass = 'jp-BuildIcon jp-SideBar-tabIcon';
|
|
|
celltools.title.caption = 'Cell Inspector';
|
|
|
celltools.id = id;
|
|
|
celltools.addItem({ tool: activeCellTool, rank: 1 });
|
|
|
celltools.addItem({ tool: slideShow, rank: 2 });
|
|
|
- celltools.addItem({ tool: nbConvert, rank: 3 });
|
|
|
celltools.addItem({ tool: metadataEditor, rank: 4 });
|
|
|
MessageLoop.installMessageHook(celltools, hook);
|
|
|
|
|
@@ -393,7 +421,7 @@ function activateNotebookHandler(
|
|
|
registry.addWidgetFactory(factory);
|
|
|
|
|
|
addCommands(app, services, tracker);
|
|
|
- populatePalette(palette);
|
|
|
+ populatePalette(palette, services);
|
|
|
|
|
|
let id = 0; // The ID counter for notebook panels.
|
|
|
|
|
@@ -471,7 +499,7 @@ function activateNotebookHandler(
|
|
|
});
|
|
|
|
|
|
// Add main menu notebook menu.
|
|
|
- populateMenus(app, mainMenu, tracker);
|
|
|
+ populateMenus(app, mainMenu, tracker, services, palette);
|
|
|
|
|
|
// Utility function to create a new notebook.
|
|
|
const createNew = (cwd: string, kernelName?: string) => {
|
|
@@ -1569,7 +1597,10 @@ function addCommands(
|
|
|
/**
|
|
|
* Populate the application's command palette with notebook commands.
|
|
|
*/
|
|
|
-function populatePalette(palette: ICommandPalette): void {
|
|
|
+function populatePalette(
|
|
|
+ palette: ICommandPalette,
|
|
|
+ services: ServiceManager
|
|
|
+): void {
|
|
|
let category = 'Notebook Operations';
|
|
|
[
|
|
|
CommandIDs.interrupt,
|
|
@@ -1601,15 +1632,6 @@ function populatePalette(palette: ICommandPalette): void {
|
|
|
args: { isPalette: true }
|
|
|
});
|
|
|
|
|
|
- EXPORT_TO_FORMATS.forEach(exportToFormat => {
|
|
|
- let args = {
|
|
|
- format: exportToFormat['format'],
|
|
|
- label: exportToFormat['label'],
|
|
|
- isPalette: true
|
|
|
- };
|
|
|
- palette.addItem({ command: CommandIDs.exportToFormat, category, args });
|
|
|
- });
|
|
|
-
|
|
|
category = 'Notebook Cell Operations';
|
|
|
[
|
|
|
CommandIDs.run,
|
|
@@ -1665,7 +1687,9 @@ function populatePalette(palette: ICommandPalette): void {
|
|
|
function populateMenus(
|
|
|
app: JupyterLab,
|
|
|
mainMenu: IMainMenu,
|
|
|
- tracker: INotebookTracker
|
|
|
+ tracker: INotebookTracker,
|
|
|
+ services: ServiceManager,
|
|
|
+ palette: ICommandPalette
|
|
|
): void {
|
|
|
let { commands } = app;
|
|
|
|
|
@@ -1731,17 +1755,38 @@ function populateMenus(
|
|
|
// Add a notebook group to the File menu.
|
|
|
let exportTo = new Menu({ commands });
|
|
|
exportTo.title.label = 'Export Notebook As…';
|
|
|
- EXPORT_TO_FORMATS.forEach(exportToFormat => {
|
|
|
- exportTo.addItem({
|
|
|
- command: CommandIDs.exportToFormat,
|
|
|
- args: exportToFormat
|
|
|
- });
|
|
|
+ services.nbconvert.getExportFormats().then(response => {
|
|
|
+ if (response) {
|
|
|
+ // convert exportList to palette and menu items
|
|
|
+ const formatList = Object.keys(response);
|
|
|
+ const category = 'Notebook Operations';
|
|
|
+ formatList.forEach(function(key) {
|
|
|
+ let capCaseKey = key[0].toUpperCase() + key.substr(1);
|
|
|
+ let labelStr = FORMAT_LABEL[key] ? FORMAT_LABEL[key] : capCaseKey;
|
|
|
+ let args = {
|
|
|
+ format: key,
|
|
|
+ label: labelStr,
|
|
|
+ isPalette: true
|
|
|
+ };
|
|
|
+ if (FORMAT_EXCLUDE.indexOf(key) === -1) {
|
|
|
+ exportTo.addItem({
|
|
|
+ command: CommandIDs.exportToFormat,
|
|
|
+ args: args
|
|
|
+ });
|
|
|
+ palette.addItem({
|
|
|
+ command: CommandIDs.exportToFormat,
|
|
|
+ category,
|
|
|
+ args
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ const fileGroup = [
|
|
|
+ { command: CommandIDs.trust },
|
|
|
+ { type: 'submenu', submenu: exportTo } as Menu.IItemOptions
|
|
|
+ ];
|
|
|
+ mainMenu.fileMenu.addGroup(fileGroup, 10);
|
|
|
+ }
|
|
|
});
|
|
|
- const fileGroup = [
|
|
|
- { command: CommandIDs.trust },
|
|
|
- { type: 'submenu', submenu: exportTo } as Menu.IItemOptions
|
|
|
- ];
|
|
|
- mainMenu.fileMenu.addGroup(fileGroup, 10);
|
|
|
|
|
|
// Add a kernel user to the Kernel menu
|
|
|
mainMenu.kernelMenu.kernelUsers.add({
|