@jupyterlab/fileeditor 4.0.0-alpha.1 → 4.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/fileeditorlspadapter.d.ts +90 -0
- package/lib/fileeditorlspadapter.js +154 -0
- package/lib/fileeditorlspadapter.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/searchprovider.d.ts +44 -0
- package/lib/searchprovider.js +53 -0
- package/lib/searchprovider.js.map +1 -0
- package/lib/toc/factory.d.ts +25 -0
- package/lib/toc/factory.js +32 -0
- package/lib/toc/factory.js.map +1 -0
- package/lib/toc/index.d.ts +4 -0
- package/lib/toc/index.js +7 -0
- package/lib/toc/index.js.map +1 -0
- package/lib/toc/latex.d.ts +48 -0
- package/lib/toc/latex.js +112 -0
- package/lib/toc/latex.js.map +1 -0
- package/lib/toc/markdown.d.ts +44 -0
- package/lib/toc/markdown.js +66 -0
- package/lib/toc/markdown.js.map +1 -0
- package/lib/toc/python.d.ts +44 -0
- package/lib/toc/python.js +114 -0
- package/lib/toc/python.js.map +1 -0
- package/lib/tokens.js +0 -2
- package/lib/tokens.js.map +1 -1
- package/lib/widget.d.ts +8 -35
- package/lib/widget.js +28 -104
- package/lib/widget.js.map +1 -1
- package/package.json +19 -16
- package/style/base.css +8 -3
- package/style/index.css +4 -0
- package/style/index.js +4 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { CodeEditor } from '@jupyterlab/codeeditor';
|
|
2
|
+
import { CodeMirrorEditor } from '@jupyterlab/codemirror';
|
|
3
|
+
import { DocumentRegistry, IDocumentWidget } from '@jupyterlab/docregistry';
|
|
4
|
+
import { IAdapterOptions, IVirtualPosition, VirtualDocument, WidgetLSPAdapter } from '@jupyterlab/lsp';
|
|
5
|
+
import { FileEditor } from './widget';
|
|
6
|
+
export interface IFileEditorAdapterOptions extends IAdapterOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The document registry instance.
|
|
9
|
+
*/
|
|
10
|
+
docRegistry: DocumentRegistry;
|
|
11
|
+
}
|
|
12
|
+
export declare class FileEditorAdapter extends WidgetLSPAdapter<IDocumentWidget<FileEditor>> {
|
|
13
|
+
constructor(editorWidget: IDocumentWidget<FileEditor>, options: IFileEditorAdapterOptions);
|
|
14
|
+
/**
|
|
15
|
+
* The wrapped `FileEditor` widget.
|
|
16
|
+
*/
|
|
17
|
+
readonly editor: FileEditor;
|
|
18
|
+
/**
|
|
19
|
+
* Get current path of the document.
|
|
20
|
+
*/
|
|
21
|
+
get documentPath(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the mime type of the document.
|
|
24
|
+
*/
|
|
25
|
+
get mimeType(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Get the file extension of the document.
|
|
28
|
+
*/
|
|
29
|
+
get languageFileExtension(): string;
|
|
30
|
+
/**
|
|
31
|
+
* Get the CM editor
|
|
32
|
+
*/
|
|
33
|
+
get ceEditor(): CodeMirrorEditor;
|
|
34
|
+
/**
|
|
35
|
+
* Get the activated CM editor.
|
|
36
|
+
*/
|
|
37
|
+
get activeEditor(): CodeEditor.IEditor;
|
|
38
|
+
/**
|
|
39
|
+
* Get the inner HTMLElement of the document widget.
|
|
40
|
+
*/
|
|
41
|
+
get wrapperElement(): HTMLElement;
|
|
42
|
+
/**
|
|
43
|
+
* Get current path of the document.
|
|
44
|
+
*/
|
|
45
|
+
get path(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Get the list of CM editors in the document, there is only one editor
|
|
48
|
+
* in the case of file editor.
|
|
49
|
+
*/
|
|
50
|
+
get editors(): {
|
|
51
|
+
ceEditor: CodeEditor.IEditor;
|
|
52
|
+
type: string;
|
|
53
|
+
}[];
|
|
54
|
+
/**
|
|
55
|
+
* Generate the virtual document associated with the document.
|
|
56
|
+
*/
|
|
57
|
+
createVirtualDocument(): VirtualDocument;
|
|
58
|
+
/**
|
|
59
|
+
* Get the index of editor from the cursor position in the virtual
|
|
60
|
+
* document. Since there is only one editor, this method always return
|
|
61
|
+
* 0
|
|
62
|
+
*
|
|
63
|
+
* @param position - the position of cursor in the virtual document.
|
|
64
|
+
* @return {number} - index of the virtual editor
|
|
65
|
+
*/
|
|
66
|
+
getEditorIndexAt(position: IVirtualPosition): number;
|
|
67
|
+
/**
|
|
68
|
+
* Get the index of input editor
|
|
69
|
+
*
|
|
70
|
+
* @param ceEditor - instance of the code editor
|
|
71
|
+
*/
|
|
72
|
+
getEditorIndex(ceEditor: CodeEditor.IEditor): number;
|
|
73
|
+
/**
|
|
74
|
+
* Get the wrapper of input editor.
|
|
75
|
+
*
|
|
76
|
+
* @param ceEditor
|
|
77
|
+
* @return {HTMLElement}
|
|
78
|
+
*/
|
|
79
|
+
getEditorWrapper(ceEditor: CodeEditor.IEditor): HTMLElement;
|
|
80
|
+
/**
|
|
81
|
+
* Initialization function called once the editor and the LSP connection
|
|
82
|
+
* manager is ready. This function will create the virtual document and
|
|
83
|
+
* connect various signals.
|
|
84
|
+
*/
|
|
85
|
+
protected initOnceReady(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* The document registry instance.
|
|
88
|
+
*/
|
|
89
|
+
private readonly _docRegistry;
|
|
90
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
4
|
+
var t = {};
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
8
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
9
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
10
|
+
t[p[i]] = s[p[i]];
|
|
11
|
+
}
|
|
12
|
+
return t;
|
|
13
|
+
};
|
|
14
|
+
import { VirtualDocument, WidgetLSPAdapter } from '@jupyterlab/lsp';
|
|
15
|
+
export class FileEditorAdapter extends WidgetLSPAdapter {
|
|
16
|
+
constructor(editorWidget, options) {
|
|
17
|
+
const { docRegistry } = options, others = __rest(options, ["docRegistry"]);
|
|
18
|
+
super(editorWidget, others);
|
|
19
|
+
this.editor = editorWidget.content;
|
|
20
|
+
this._docRegistry = docRegistry;
|
|
21
|
+
this.ready = new Promise((resolve, reject) => {
|
|
22
|
+
this.initOnceReady().then(resolve).catch(reject);
|
|
23
|
+
});
|
|
24
|
+
// Dispose the adapter when the editor is disposed.
|
|
25
|
+
editorWidget.disposed.connect(() => this.dispose());
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get current path of the document.
|
|
29
|
+
*/
|
|
30
|
+
get documentPath() {
|
|
31
|
+
return this.widget.context.path;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the mime type of the document.
|
|
35
|
+
*/
|
|
36
|
+
get mimeType() {
|
|
37
|
+
const codeMirrorMimeType = this.editor.model.mimeType;
|
|
38
|
+
const contentsModel = this.editor.context.contentsModel;
|
|
39
|
+
// when MIME type is not known it defaults to 'text/plain',
|
|
40
|
+
// so if it is different we can accept it as it is
|
|
41
|
+
if (codeMirrorMimeType != 'text/plain') {
|
|
42
|
+
return codeMirrorMimeType;
|
|
43
|
+
}
|
|
44
|
+
else if (contentsModel) {
|
|
45
|
+
// a script that does not have a MIME type known by the editor
|
|
46
|
+
// (no syntax highlight mode), can still be known by the document
|
|
47
|
+
// registry (and this is arguably easier to extend).
|
|
48
|
+
let fileType = this._docRegistry.getFileTypeForModel(contentsModel);
|
|
49
|
+
return fileType.mimeTypes[0];
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
// "text/plain" this is
|
|
53
|
+
return codeMirrorMimeType;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get the file extension of the document.
|
|
58
|
+
*/
|
|
59
|
+
get languageFileExtension() {
|
|
60
|
+
let parts = this.documentPath.split('.');
|
|
61
|
+
return parts[parts.length - 1];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the CM editor
|
|
65
|
+
*/
|
|
66
|
+
get ceEditor() {
|
|
67
|
+
return this.editor.editor;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the activated CM editor.
|
|
71
|
+
*/
|
|
72
|
+
get activeEditor() {
|
|
73
|
+
return this.editor.editor;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the inner HTMLElement of the document widget.
|
|
77
|
+
*/
|
|
78
|
+
get wrapperElement() {
|
|
79
|
+
return this.widget.node;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get current path of the document.
|
|
83
|
+
*/
|
|
84
|
+
get path() {
|
|
85
|
+
return this.widget.context.path;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the list of CM editors in the document, there is only one editor
|
|
89
|
+
* in the case of file editor.
|
|
90
|
+
*/
|
|
91
|
+
get editors() {
|
|
92
|
+
return [{ ceEditor: this.editor.editor, type: 'code' }];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Generate the virtual document associated with the document.
|
|
96
|
+
*/
|
|
97
|
+
createVirtualDocument() {
|
|
98
|
+
return new VirtualDocument({
|
|
99
|
+
language: this.language,
|
|
100
|
+
foreignCodeExtractors: this.options.foreignCodeExtractorsManager,
|
|
101
|
+
path: this.documentPath,
|
|
102
|
+
fileExtension: this.languageFileExtension,
|
|
103
|
+
// notebooks are continuous, each cell is dependent on the previous one
|
|
104
|
+
standalone: true,
|
|
105
|
+
// notebooks are not supported by LSP servers
|
|
106
|
+
hasLspSupportedFile: true
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get the index of editor from the cursor position in the virtual
|
|
111
|
+
* document. Since there is only one editor, this method always return
|
|
112
|
+
* 0
|
|
113
|
+
*
|
|
114
|
+
* @param position - the position of cursor in the virtual document.
|
|
115
|
+
* @return {number} - index of the virtual editor
|
|
116
|
+
*/
|
|
117
|
+
getEditorIndexAt(position) {
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the index of input editor
|
|
122
|
+
*
|
|
123
|
+
* @param ceEditor - instance of the code editor
|
|
124
|
+
*/
|
|
125
|
+
getEditorIndex(ceEditor) {
|
|
126
|
+
return 0;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get the wrapper of input editor.
|
|
130
|
+
*
|
|
131
|
+
* @param ceEditor
|
|
132
|
+
* @return {HTMLElement}
|
|
133
|
+
*/
|
|
134
|
+
getEditorWrapper(ceEditor) {
|
|
135
|
+
return this.wrapperElement;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Initialization function called once the editor and the LSP connection
|
|
139
|
+
* manager is ready. This function will create the virtual document and
|
|
140
|
+
* connect various signals.
|
|
141
|
+
*/
|
|
142
|
+
async initOnceReady() {
|
|
143
|
+
if (!this.editor.context.isReady) {
|
|
144
|
+
await this.editor.context.ready;
|
|
145
|
+
}
|
|
146
|
+
await this.connectionManager.ready;
|
|
147
|
+
this.initVirtual();
|
|
148
|
+
// connect the document, but do not open it as the adapter will handle this
|
|
149
|
+
// after registering all features
|
|
150
|
+
this.connectDocument(this.virtualDocument, false).catch(console.warn);
|
|
151
|
+
this.editor.model.mimeTypeChanged.connect(this.reloadConnection, this);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=fileeditorlspadapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileeditorlspadapter.js","sourceRoot":"","sources":["../src/fileeditorlspadapter.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* @packageDocumentation
|
|
5
5
|
* @module fileeditor
|
|
6
6
|
*/
|
|
7
|
+
export * from './fileeditorlspadapter';
|
|
8
|
+
export * from './searchprovider';
|
|
7
9
|
export * from './tabspacestatus';
|
|
10
|
+
export * from './toc';
|
|
8
11
|
export * from './tokens';
|
|
9
12
|
export * from './widget';
|
|
10
13
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAC3D;;;GAGG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAC3D;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { MainAreaWidget } from '@jupyterlab/apputils';
|
|
2
|
+
import { CodeMirrorSearchProvider } from '@jupyterlab/codemirror';
|
|
3
|
+
import { ISearchProvider } from '@jupyterlab/documentsearch';
|
|
4
|
+
import { ITranslator } from '@jupyterlab/translation';
|
|
5
|
+
import { Widget } from '@lumino/widgets';
|
|
6
|
+
import { FileEditor } from './widget';
|
|
7
|
+
/**
|
|
8
|
+
* Helper type
|
|
9
|
+
*/
|
|
10
|
+
export declare type FileEditorPanel = MainAreaWidget<FileEditor>;
|
|
11
|
+
/**
|
|
12
|
+
* File editor search provider
|
|
13
|
+
*/
|
|
14
|
+
export declare class FileEditorSearchProvider extends CodeMirrorSearchProvider implements ISearchProvider {
|
|
15
|
+
/**
|
|
16
|
+
* Constructor
|
|
17
|
+
* @param widget File editor panel
|
|
18
|
+
*/
|
|
19
|
+
constructor(widget: FileEditorPanel);
|
|
20
|
+
/**
|
|
21
|
+
* Instantiate a search provider for the widget.
|
|
22
|
+
*
|
|
23
|
+
* #### Notes
|
|
24
|
+
* The widget provided is always checked using `isApplicable` before calling
|
|
25
|
+
* this factory.
|
|
26
|
+
*
|
|
27
|
+
* @param widget The widget to search on
|
|
28
|
+
* @param translator [optional] The translator object
|
|
29
|
+
*
|
|
30
|
+
* @returns The search provider on the widget
|
|
31
|
+
*/
|
|
32
|
+
static createNew(widget: FileEditorPanel, translator?: ITranslator): ISearchProvider;
|
|
33
|
+
/**
|
|
34
|
+
* Report whether or not this provider has the ability to search on the given object
|
|
35
|
+
*/
|
|
36
|
+
static isApplicable(domain: Widget): domain is FileEditorPanel;
|
|
37
|
+
/**
|
|
38
|
+
* Get an initial query value if applicable so that it can be entered
|
|
39
|
+
* into the search box as an initial query
|
|
40
|
+
*
|
|
41
|
+
* @returns Initial value used to populate the search box.
|
|
42
|
+
*/
|
|
43
|
+
getInitialQuery(): string;
|
|
44
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
import { MainAreaWidget } from '@jupyterlab/apputils';
|
|
4
|
+
import { CodeMirrorEditor, CodeMirrorSearchProvider } from '@jupyterlab/codemirror';
|
|
5
|
+
import { FileEditor } from './widget';
|
|
6
|
+
/**
|
|
7
|
+
* File editor search provider
|
|
8
|
+
*/
|
|
9
|
+
export class FileEditorSearchProvider extends CodeMirrorSearchProvider {
|
|
10
|
+
/**
|
|
11
|
+
* Constructor
|
|
12
|
+
* @param widget File editor panel
|
|
13
|
+
*/
|
|
14
|
+
constructor(widget) {
|
|
15
|
+
super(widget.content.editor);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Instantiate a search provider for the widget.
|
|
19
|
+
*
|
|
20
|
+
* #### Notes
|
|
21
|
+
* The widget provided is always checked using `isApplicable` before calling
|
|
22
|
+
* this factory.
|
|
23
|
+
*
|
|
24
|
+
* @param widget The widget to search on
|
|
25
|
+
* @param translator [optional] The translator object
|
|
26
|
+
*
|
|
27
|
+
* @returns The search provider on the widget
|
|
28
|
+
*/
|
|
29
|
+
static createNew(widget, translator) {
|
|
30
|
+
return new FileEditorSearchProvider(widget);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Report whether or not this provider has the ability to search on the given object
|
|
34
|
+
*/
|
|
35
|
+
static isApplicable(domain) {
|
|
36
|
+
return (domain instanceof MainAreaWidget &&
|
|
37
|
+
domain.content instanceof FileEditor &&
|
|
38
|
+
domain.content.editor instanceof CodeMirrorEditor);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get an initial query value if applicable so that it can be entered
|
|
42
|
+
* into the search box as an initial query
|
|
43
|
+
*
|
|
44
|
+
* @returns Initial value used to populate the search box.
|
|
45
|
+
*/
|
|
46
|
+
getInitialQuery() {
|
|
47
|
+
const cm = this.editor;
|
|
48
|
+
const selection = cm.state.sliceDoc(cm.state.selection.main.from, cm.state.selection.main.to);
|
|
49
|
+
// if there are newlines, just return empty string
|
|
50
|
+
return selection.search(/\r?\n|\r/g) === -1 ? selection : '';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=searchprovider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchprovider.js","sourceRoot":"","sources":["../src/searchprovider.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACzB,MAAM,wBAAwB,CAAC;AAIhC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAOtC;;GAEG;AACH,MAAM,OAAO,wBACX,SAAQ,wBAAwB;IAGhC;;;OAGG;IACH,YAAY,MAAuB;QACjC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAA0B,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,SAAS,CACd,MAAuB,EACvB,UAAwB;QAExB,OAAO,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,MAAc;QAChC,OAAO,CACL,MAAM,YAAY,cAAc;YAChC,MAAM,CAAC,OAAO,YAAY,UAAU;YACpC,MAAM,CAAC,OAAO,CAAC,MAAM,YAAY,gBAAgB,CAClD,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,eAAe;QACb,MAAM,EAAE,GAAG,IAAI,CAAC,MAA0B,CAAC;QAC3C,MAAM,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CACjC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAC5B,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAC3B,CAAC;QACF,kDAAkD;QAClD,OAAO,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/D,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DocumentRegistry, IDocumentWidget } from '@jupyterlab/docregistry';
|
|
2
|
+
import { TableOfContents, TableOfContentsFactory, TableOfContentsModel } from '@jupyterlab/toc';
|
|
3
|
+
import { FileEditor } from '../widget';
|
|
4
|
+
/**
|
|
5
|
+
* Interface describing a file editor heading.
|
|
6
|
+
*/
|
|
7
|
+
export interface IEditorHeading extends TableOfContents.IHeading {
|
|
8
|
+
/**
|
|
9
|
+
* Heading line number.
|
|
10
|
+
*/
|
|
11
|
+
line: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Base table of contents model factory for file editor
|
|
15
|
+
*/
|
|
16
|
+
export declare abstract class EditorTableOfContentsFactory extends TableOfContentsFactory<IDocumentWidget<FileEditor>> {
|
|
17
|
+
/**
|
|
18
|
+
* Create a new table of contents model for the widget
|
|
19
|
+
*
|
|
20
|
+
* @param widget - widget
|
|
21
|
+
* @param configuration - Table of contents configuration
|
|
22
|
+
* @returns The table of contents model
|
|
23
|
+
*/
|
|
24
|
+
createNew(widget: IDocumentWidget<FileEditor, DocumentRegistry.IModel>, configuration?: TableOfContents.IConfig): TableOfContentsModel<IEditorHeading, IDocumentWidget<FileEditor, DocumentRegistry.IModel>>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
import { TableOfContentsFactory } from '@jupyterlab/toc';
|
|
4
|
+
/**
|
|
5
|
+
* Base table of contents model factory for file editor
|
|
6
|
+
*/
|
|
7
|
+
export class EditorTableOfContentsFactory extends TableOfContentsFactory {
|
|
8
|
+
/**
|
|
9
|
+
* Create a new table of contents model for the widget
|
|
10
|
+
*
|
|
11
|
+
* @param widget - widget
|
|
12
|
+
* @param configuration - Table of contents configuration
|
|
13
|
+
* @returns The table of contents model
|
|
14
|
+
*/
|
|
15
|
+
createNew(widget, configuration) {
|
|
16
|
+
const model = super.createNew(widget, configuration);
|
|
17
|
+
const onActiveHeadingChanged = (model, heading) => {
|
|
18
|
+
if (heading) {
|
|
19
|
+
widget.content.editor.setCursorPosition({
|
|
20
|
+
line: heading.line,
|
|
21
|
+
column: 0
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
model.activeHeadingChanged.connect(onActiveHeadingChanged);
|
|
26
|
+
widget.disposed.connect(() => {
|
|
27
|
+
model.activeHeadingChanged.disconnect(onActiveHeadingChanged);
|
|
28
|
+
});
|
|
29
|
+
return model;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/toc/factory.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAG3D,OAAO,EAEL,sBAAsB,EAEvB,MAAM,iBAAiB,CAAC;AAazB;;GAEG;AACH,MAAM,OAAgB,4BAA6B,SAAQ,sBAE1D;IACC;;;;;;OAMG;IACH,SAAS,CACP,MAA4D,EAC5D,aAAuC;QAKvC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAC3B,MAAM,EACN,aAAa,CAId,CAAC;QAEF,MAAM,sBAAsB,GAAG,CAC7B,KAGC,EACD,OAA8B,EAC9B,EAAE;YACF,IAAI,OAAO,EAAE;gBACX,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC;oBACtC,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,MAAM,EAAE,CAAC;iBACV,CAAC,CAAC;aACJ;QACH,CAAC,CAAC;QAEF,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QAC3D,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE;YAC3B,KAAK,CAAC,oBAAoB,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|
package/lib/toc/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/toc/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAE3D,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DocumentRegistry, IDocumentWidget } from '@jupyterlab/docregistry';
|
|
2
|
+
import { TableOfContents, TableOfContentsModel } from '@jupyterlab/toc';
|
|
3
|
+
import { Widget } from '@lumino/widgets';
|
|
4
|
+
import { FileEditor } from '../widget';
|
|
5
|
+
import { EditorTableOfContentsFactory, IEditorHeading } from './factory';
|
|
6
|
+
/**
|
|
7
|
+
* Table of content model for LaTeX files.
|
|
8
|
+
*/
|
|
9
|
+
export declare class LaTeXTableOfContentsModel extends TableOfContentsModel<IEditorHeading, IDocumentWidget<FileEditor, DocumentRegistry.IModel>> {
|
|
10
|
+
/**
|
|
11
|
+
* Type of document supported by the model.
|
|
12
|
+
*
|
|
13
|
+
* #### Notes
|
|
14
|
+
* A `data-document-type` attribute with this value will be set
|
|
15
|
+
* on the tree view `.jp-TableOfContents-content[data-document-type="..."]`
|
|
16
|
+
*/
|
|
17
|
+
get documentType(): string;
|
|
18
|
+
/**
|
|
19
|
+
* List of configuration options supported by the model.
|
|
20
|
+
*/
|
|
21
|
+
get supportedOptions(): (keyof TableOfContents.IConfig)[];
|
|
22
|
+
/**
|
|
23
|
+
* Produce the headings for a document.
|
|
24
|
+
*
|
|
25
|
+
* @returns The list of new headings or `null` if nothing needs to be updated.
|
|
26
|
+
*/
|
|
27
|
+
protected getHeadings(): Promise<IEditorHeading[] | null>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Table of content model factory for LaTeX files.
|
|
31
|
+
*/
|
|
32
|
+
export declare class LaTeXTableOfContentsFactory extends EditorTableOfContentsFactory {
|
|
33
|
+
/**
|
|
34
|
+
* Whether the factory can handle the widget or not.
|
|
35
|
+
*
|
|
36
|
+
* @param widget - widget
|
|
37
|
+
* @returns boolean indicating a ToC can be generated
|
|
38
|
+
*/
|
|
39
|
+
isApplicable(widget: Widget): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Create a new table of contents model for the widget
|
|
42
|
+
*
|
|
43
|
+
* @param widget - widget
|
|
44
|
+
* @param configuration - Table of contents configuration
|
|
45
|
+
* @returns The table of contents model
|
|
46
|
+
*/
|
|
47
|
+
protected _createNew(widget: IDocumentWidget<FileEditor, DocumentRegistry.IModel>, configuration?: TableOfContents.IConfig): LaTeXTableOfContentsModel;
|
|
48
|
+
}
|
package/lib/toc/latex.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Copyright (c) Jupyter Development Team.
|
|
2
|
+
// Distributed under the terms of the Modified BSD License.
|
|
3
|
+
import { TableOfContentsModel, TableOfContentsUtils } from '@jupyterlab/toc';
|
|
4
|
+
import { EditorTableOfContentsFactory } from './factory';
|
|
5
|
+
/**
|
|
6
|
+
* Maps LaTeX section headings to HTML header levels.
|
|
7
|
+
*
|
|
8
|
+
* ## Notes
|
|
9
|
+
*
|
|
10
|
+
* - As `part` and `chapter` section headings appear to be less common, assign them to heading level 1.
|
|
11
|
+
*
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
const LATEX_LEVELS = {
|
|
15
|
+
part: 1,
|
|
16
|
+
chapter: 1,
|
|
17
|
+
section: 1,
|
|
18
|
+
subsection: 2,
|
|
19
|
+
subsubsection: 3,
|
|
20
|
+
paragraph: 4,
|
|
21
|
+
subparagraph: 5
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Regular expression to create the outline
|
|
25
|
+
*/
|
|
26
|
+
const SECTIONS = /^\s*\\(section|subsection|subsubsection){(.+)}/;
|
|
27
|
+
/**
|
|
28
|
+
* Table of content model for LaTeX files.
|
|
29
|
+
*/
|
|
30
|
+
export class LaTeXTableOfContentsModel extends TableOfContentsModel {
|
|
31
|
+
/**
|
|
32
|
+
* Type of document supported by the model.
|
|
33
|
+
*
|
|
34
|
+
* #### Notes
|
|
35
|
+
* A `data-document-type` attribute with this value will be set
|
|
36
|
+
* on the tree view `.jp-TableOfContents-content[data-document-type="..."]`
|
|
37
|
+
*/
|
|
38
|
+
get documentType() {
|
|
39
|
+
return 'latex';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* List of configuration options supported by the model.
|
|
43
|
+
*/
|
|
44
|
+
get supportedOptions() {
|
|
45
|
+
return ['maximalDepth', 'numberHeaders'];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Produce the headings for a document.
|
|
49
|
+
*
|
|
50
|
+
* @returns The list of new headings or `null` if nothing needs to be updated.
|
|
51
|
+
*/
|
|
52
|
+
getHeadings() {
|
|
53
|
+
if (!this.isActive) {
|
|
54
|
+
return Promise.resolve(null);
|
|
55
|
+
}
|
|
56
|
+
// Split the text into lines:
|
|
57
|
+
const lines = this.widget.content.model.value.text.split('\n');
|
|
58
|
+
const levels = new Array();
|
|
59
|
+
let previousLevel = levels.length;
|
|
60
|
+
const headings = new Array();
|
|
61
|
+
for (let i = 0; i < lines.length; i++) {
|
|
62
|
+
const match = lines[i].match(SECTIONS);
|
|
63
|
+
if (match) {
|
|
64
|
+
const level = LATEX_LEVELS[match[1]];
|
|
65
|
+
if (level <= this.configuration.maximalDepth) {
|
|
66
|
+
const prefix = TableOfContentsUtils.getPrefix(level, previousLevel, levels, Object.assign(Object.assign({}, this.configuration), {
|
|
67
|
+
// Force base numbering and numbering first level
|
|
68
|
+
baseNumbering: 1, numberingH1: true }));
|
|
69
|
+
previousLevel = level;
|
|
70
|
+
headings.push({
|
|
71
|
+
text: match[2],
|
|
72
|
+
prefix: prefix,
|
|
73
|
+
level,
|
|
74
|
+
line: i
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return Promise.resolve(headings);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Table of content model factory for LaTeX files.
|
|
84
|
+
*/
|
|
85
|
+
export class LaTeXTableOfContentsFactory extends EditorTableOfContentsFactory {
|
|
86
|
+
/**
|
|
87
|
+
* Whether the factory can handle the widget or not.
|
|
88
|
+
*
|
|
89
|
+
* @param widget - widget
|
|
90
|
+
* @returns boolean indicating a ToC can be generated
|
|
91
|
+
*/
|
|
92
|
+
isApplicable(widget) {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
const isApplicable = super.isApplicable(widget);
|
|
95
|
+
if (isApplicable) {
|
|
96
|
+
let mime = (_b = (_a = widget.content) === null || _a === void 0 ? void 0 : _a.model) === null || _b === void 0 ? void 0 : _b.mimeType;
|
|
97
|
+
return mime && (mime === 'text/x-latex' || mime === 'text/x-stex');
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Create a new table of contents model for the widget
|
|
103
|
+
*
|
|
104
|
+
* @param widget - widget
|
|
105
|
+
* @param configuration - Table of contents configuration
|
|
106
|
+
* @returns The table of contents model
|
|
107
|
+
*/
|
|
108
|
+
_createNew(widget, configuration) {
|
|
109
|
+
return new LaTeXTableOfContentsModel(widget, configuration);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=latex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latex.js","sourceRoot":"","sources":["../../src/toc/latex.ts"],"names":[],"mappings":"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"}
|