|
@@ -1,21 +1,21 @@
|
|
|
// Copyright (c) Jupyter Development Team.
|
|
|
// Distributed under the terms of the Modified BSD License.
|
|
|
|
|
|
-import {IInstanceTracker, ISanitizer} from '@jupyterlab/apputils';
|
|
|
+import { IInstanceTracker, ISanitizer } from '@jupyterlab/apputils';
|
|
|
|
|
|
-import {CodeCell, CodeCellModel, MarkdownCell} from '@jupyterlab/cells';
|
|
|
+import { CodeCell, CodeCellModel, MarkdownCell } from '@jupyterlab/cells';
|
|
|
|
|
|
-import {IDocumentWidget, MimeDocument} from '@jupyterlab/docregistry';
|
|
|
+import { IDocumentWidget, MimeDocument } from '@jupyterlab/docregistry';
|
|
|
|
|
|
-import {FileEditor, IEditorTracker} from '@jupyterlab/fileeditor';
|
|
|
+import { FileEditor, IEditorTracker } from '@jupyterlab/fileeditor';
|
|
|
|
|
|
-import {INotebookTracker, NotebookPanel} from '@jupyterlab/notebook';
|
|
|
+import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
|
|
|
|
|
|
-import {each} from '@phosphor/algorithm';
|
|
|
+import { each } from '@phosphor/algorithm';
|
|
|
|
|
|
-import {TableOfContentsRegistry} from './registry';
|
|
|
+import { TableOfContentsRegistry } from './registry';
|
|
|
|
|
|
-import {IHeading} from './toc';
|
|
|
+import { IHeading } from './toc';
|
|
|
|
|
|
const VDOM_MIME_TYPE = 'application/vdom.v1+json';
|
|
|
|
|
@@ -30,7 +30,7 @@ const HTML_MIME_TYPE = 'text/html';
|
|
|
*/
|
|
|
export function createNotebookGenerator(
|
|
|
tracker: INotebookTracker,
|
|
|
- sanitizer: ISanitizer,
|
|
|
+ sanitizer: ISanitizer
|
|
|
): TableOfContentsRegistry.IGenerator<NotebookPanel> {
|
|
|
return {
|
|
|
tracker,
|
|
@@ -49,7 +49,7 @@ export function createNotebookGenerator(
|
|
|
const outputModel = (model as CodeCellModel).outputs.get(i);
|
|
|
const dataTypes = Object.keys(outputModel.data);
|
|
|
const htmlData = dataTypes.filter(
|
|
|
- t => Private.isMarkdown(t) || Private.isDOM(t),
|
|
|
+ t => Private.isMarkdown(t) || Private.isDOM(t)
|
|
|
);
|
|
|
if (!htmlData.length) {
|
|
|
continue;
|
|
@@ -66,8 +66,8 @@ export function createNotebookGenerator(
|
|
|
Private.getRenderedHTMLHeadings(
|
|
|
outputWidget.node,
|
|
|
onClickFactory,
|
|
|
- sanitizer,
|
|
|
- ),
|
|
|
+ sanitizer
|
|
|
+ )
|
|
|
);
|
|
|
}
|
|
|
} else if (model.type === 'markdown') {
|
|
@@ -88,26 +88,26 @@ export function createNotebookGenerator(
|
|
|
Private.getRenderedHTMLHeadings(
|
|
|
cell.node,
|
|
|
onClickFactory,
|
|
|
- sanitizer,
|
|
|
- ),
|
|
|
+ sanitizer
|
|
|
+ )
|
|
|
);
|
|
|
} else {
|
|
|
const onClickFactory = (line: number) => {
|
|
|
return () => {
|
|
|
cell.node.scrollIntoView();
|
|
|
if (!(cell as MarkdownCell).rendered) {
|
|
|
- cell.editor.setCursorPosition({line, column: 0});
|
|
|
+ cell.editor.setCursorPosition({ line, column: 0 });
|
|
|
}
|
|
|
};
|
|
|
};
|
|
|
headings = headings.concat(
|
|
|
- Private.getMarkdownHeadings(model.value.text, onClickFactory),
|
|
|
+ Private.getMarkdownHeadings(model.value.text, onClickFactory)
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
return headings;
|
|
|
- },
|
|
|
+ }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -119,7 +119,7 @@ export function createNotebookGenerator(
|
|
|
* @returns A TOC generator that can parse markdown files.
|
|
|
*/
|
|
|
export function createMarkdownGenerator(
|
|
|
- tracker: IEditorTracker,
|
|
|
+ tracker: IEditorTracker
|
|
|
): TableOfContentsRegistry.IGenerator<IDocumentWidget<FileEditor>> {
|
|
|
return {
|
|
|
tracker,
|
|
@@ -133,11 +133,11 @@ export function createMarkdownGenerator(
|
|
|
let model = editor.content.model;
|
|
|
let onClickFactory = (line: number) => {
|
|
|
return () => {
|
|
|
- editor.content.editor.setCursorPosition({line, column: 0});
|
|
|
+ editor.content.editor.setCursorPosition({ line, column: 0 });
|
|
|
};
|
|
|
};
|
|
|
return Private.getMarkdownHeadings(model.value.text, onClickFactory);
|
|
|
- },
|
|
|
+ }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -150,7 +150,7 @@ export function createMarkdownGenerator(
|
|
|
*/
|
|
|
export function createRenderedMarkdownGenerator(
|
|
|
tracker: IInstanceTracker<MimeDocument>,
|
|
|
- sanitizer: ISanitizer,
|
|
|
+ sanitizer: ISanitizer
|
|
|
): TableOfContentsRegistry.IGenerator<MimeDocument> {
|
|
|
return {
|
|
|
tracker,
|
|
@@ -169,9 +169,9 @@ export function createRenderedMarkdownGenerator(
|
|
|
return Private.getRenderedHTMLHeadings(
|
|
|
widget.content.node,
|
|
|
onClickFactory,
|
|
|
- sanitizer,
|
|
|
+ sanitizer
|
|
|
);
|
|
|
- },
|
|
|
+ }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -183,7 +183,7 @@ export function createRenderedMarkdownGenerator(
|
|
|
* @returns A TOC generator that can parse LaTeX files.
|
|
|
*/
|
|
|
export function createLatexGenerator(
|
|
|
- tracker: IEditorTracker,
|
|
|
+ tracker: IEditorTracker
|
|
|
): TableOfContentsRegistry.IGenerator<IDocumentWidget<FileEditor>> {
|
|
|
return {
|
|
|
tracker,
|
|
@@ -202,26 +202,29 @@ export function createLatexGenerator(
|
|
|
// We will use the line number to scroll the editor upon
|
|
|
// TOC item click.
|
|
|
const lines = model.value.text.split('\n').map((value, idx) => {
|
|
|
- return {value, idx};
|
|
|
+ return { value, idx };
|
|
|
});
|
|
|
|
|
|
// Iterate over the lines to get the header level and
|
|
|
// the text for the line.
|
|
|
lines.forEach(line => {
|
|
|
const match = line.value.match(
|
|
|
- /^\s*\\(section|subsection|subsubsection){(.+)}/,
|
|
|
+ /^\s*\\(section|subsection|subsubsection){(.+)}/
|
|
|
);
|
|
|
if (match) {
|
|
|
const level = Private.latexLevels[match[1]];
|
|
|
const text = match[2];
|
|
|
const onClick = () => {
|
|
|
- editor.content.editor.setCursorPosition({line: line.idx, column: 0});
|
|
|
+ editor.content.editor.setCursorPosition({
|
|
|
+ line: line.idx,
|
|
|
+ column: 0
|
|
|
+ });
|
|
|
};
|
|
|
- headings.push({text, level, onClick});
|
|
|
+ headings.push({ text, level, onClick });
|
|
|
}
|
|
|
});
|
|
|
return headings;
|
|
|
- },
|
|
|
+ }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -235,7 +238,7 @@ namespace Private {
|
|
|
*/
|
|
|
export function getMarkdownHeadings(
|
|
|
text: string,
|
|
|
- onClickFactory: (line: number) => (() => void),
|
|
|
+ onClickFactory: (line: number) => (() => void)
|
|
|
): IHeading[] {
|
|
|
// Split the text into lines.
|
|
|
const lines = text.split('\n');
|
|
@@ -253,7 +256,7 @@ namespace Private {
|
|
|
const level = match[1].length;
|
|
|
// Take special care to parse markdown links into raw text.
|
|
|
const text = match[2].replace(/\[(.+)\]\(.+\)/g, '$1');
|
|
|
- headings.push({text, level, onClick});
|
|
|
+ headings.push({ text, level, onClick });
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -263,7 +266,7 @@ namespace Private {
|
|
|
const level = match[1][0] === '=' ? 1 : 2;
|
|
|
// Take special care to parse markdown links into raw text.
|
|
|
const text = lines[idx - 1].replace(/\[(.+)\]\(.+\)/g, '$1');
|
|
|
- headings.push({text, level, onClick});
|
|
|
+ headings.push({ text, level, onClick });
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -274,7 +277,7 @@ namespace Private {
|
|
|
if (match) {
|
|
|
const level = parseInt(match[1]);
|
|
|
const text = match[2];
|
|
|
- headings.push({text, level, onClick});
|
|
|
+ headings.push({ text, level, onClick });
|
|
|
}
|
|
|
});
|
|
|
return headings;
|
|
@@ -287,7 +290,7 @@ namespace Private {
|
|
|
export function getRenderedHTMLHeadings(
|
|
|
node: HTMLElement,
|
|
|
onClickFactory: (el: Element) => (() => void),
|
|
|
- sanitizer: ISanitizer,
|
|
|
+ sanitizer: ISanitizer
|
|
|
): IHeading[] {
|
|
|
let headings: IHeading[] = [];
|
|
|
let headingNodes = node.querySelectorAll('h1, h2, h3, h4, h5, h6');
|
|
@@ -299,7 +302,7 @@ namespace Private {
|
|
|
html = html.replace('¶', ''); // Remove the anchor symbol.
|
|
|
|
|
|
const onClick = onClickFactory(heading);
|
|
|
- headings.push({level, text, html, onClick});
|
|
|
+ headings.push({ level, text, html, onClick });
|
|
|
}
|
|
|
return headings;
|
|
|
}
|
|
@@ -320,10 +323,7 @@ namespace Private {
|
|
|
* Return whether the mime type is DOM-ish (html or vdom).
|
|
|
*/
|
|
|
export function isDOM(mime: string): boolean {
|
|
|
- return (
|
|
|
- mime === VDOM_MIME_TYPE ||
|
|
|
- mime === HTML_MIME_TYPE
|
|
|
- );
|
|
|
+ return mime === VDOM_MIME_TYPE || mime === HTML_MIME_TYPE;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -331,14 +331,14 @@ namespace Private {
|
|
|
* levels. `part` and `chapter` are less common in my experience,
|
|
|
* so assign them to header level 1.
|
|
|
*/
|
|
|
- export const latexLevels: {[label: string]: number} = {
|
|
|
+ export const latexLevels: { [label: string]: number } = {
|
|
|
part: 1, // Only available for report and book classes
|
|
|
chapter: 1, // Only available for report and book classes
|
|
|
section: 1,
|
|
|
subsection: 2,
|
|
|
subsubsection: 3,
|
|
|
paragraph: 4,
|
|
|
- subparagraph: 5,
|
|
|
+ subparagraph: 5
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -360,7 +360,7 @@ namespace Private {
|
|
|
'div',
|
|
|
'span',
|
|
|
'pre',
|
|
|
- 'del',
|
|
|
+ 'del'
|
|
|
],
|
|
|
allowedAttributes: {
|
|
|
// Allow "class" attribute for <code> tags.
|
|
@@ -372,7 +372,7 @@ namespace Private {
|
|
|
// Allow "class" attribute for <p> tags.
|
|
|
p: ['class'],
|
|
|
// Allow "class" attribute for <pre> tags.
|
|
|
- pre: ['class'],
|
|
|
- },
|
|
|
+ pre: ['class']
|
|
|
+ }
|
|
|
};
|
|
|
}
|