@jupyterlab/mermaid 4.1.0-alpha.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,2DAA2D;AAE3D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,gCAAgC;AAChC,MAAM,CAAC,MAAM,iBAAiB,GAAG,kBAAkB,CAAC;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAE5D,iBAAiB;AACjB,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAEzC,MAAM;AACN,MAAM,CAAC,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAC9C,MAAM,CAAC,MAAM,aAAa,GAAG,4BAA4B,CAAC;AAC1D,MAAM,CAAC,MAAM,aAAa,GAAG,4BAA4B,CAAC;AAE1D;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,KAAK,CACtC,qCAAqC,EACrC,qDAAqD,CACtD,CAAC;AAqDF;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,KAAK,CACvC,sCAAsC,EACtC,oFAAoF,CACrF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@jupyterlab/mermaid",
3
+ "version": "4.1.0-alpha.1",
4
+ "description": "JupyterLab - Mermaid Renderer",
5
+ "homepage": "https://github.com/jupyterlab/jupyterlab",
6
+ "bugs": {
7
+ "url": "https://github.com/jupyterlab/jupyterlab/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/jupyterlab/jupyterlab.git"
12
+ },
13
+ "license": "BSD-3-Clause",
14
+ "author": "Project Jupyter",
15
+ "sideEffects": [
16
+ "style/*.css",
17
+ "style/index.js"
18
+ ],
19
+ "main": "lib/index.js",
20
+ "types": "lib/index.d.ts",
21
+ "style": "style/index.css",
22
+ "directories": {
23
+ "lib": "lib/"
24
+ },
25
+ "files": [
26
+ "lib/*.d.ts",
27
+ "lib/*.js.map",
28
+ "lib/*.js",
29
+ "style/*.css",
30
+ "style/index.js",
31
+ "src/**/*.{ts,tsx}"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsc -b",
35
+ "clean": "rimraf lib && rimraf tsconfig.tsbuildinfo",
36
+ "docs": "typedoc src",
37
+ "test": "jest",
38
+ "test:cov": "jest --collect-coverage",
39
+ "test:debug": "node --inspect-brk ../../node_modules/.bin/jest --runInBand",
40
+ "test:debug:watch": "node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch",
41
+ "watch": "tsc -b --watch"
42
+ },
43
+ "dependencies": {
44
+ "@jupyterlab/apputils": "^4.2.0-alpha.1",
45
+ "@jupyterlab/coreutils": "^6.1.0-alpha.1",
46
+ "@jupyterlab/rendermime-interfaces": "^3.8.3-alpha.0",
47
+ "@lumino/coreutils": "^2.1.2",
48
+ "@lumino/widgets": "^2.3.0",
49
+ "mermaid": "^10.3.1"
50
+ },
51
+ "devDependencies": {
52
+ "@types/jest": "^29.2.0",
53
+ "jest": "^29.2.0",
54
+ "rimraf": "~3.0.0",
55
+ "typedoc": "~0.24.7",
56
+ "typescript": "~5.0.4"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "styleModule": "style/index.js"
62
+ }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+ /**
4
+ * @packageDocumentation
5
+ * @module mermaid
6
+ */
7
+
8
+ export * from './manager';
9
+ export * from './markdown';
10
+ export * from './mime';
11
+ export * from './tokens';
package/src/manager.ts ADDED
@@ -0,0 +1,325 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ import type MermaidType from 'mermaid';
5
+
6
+ import { PromiseDelegate } from '@lumino/coreutils';
7
+
8
+ import { LruCache } from '@jupyterlab/coreutils';
9
+
10
+ import { IThemeManager } from '@jupyterlab/apputils';
11
+
12
+ import {
13
+ DETAILS_CLASS,
14
+ IMermaidManager,
15
+ MERMAID_CLASS,
16
+ MERMAID_CODE_CLASS,
17
+ MERMAID_DARK_THEME,
18
+ MERMAID_DEFAULT_THEME,
19
+ SUMMARY_CLASS,
20
+ WARNING_CLASS
21
+ } from './tokens';
22
+
23
+ /**
24
+ * A mermaid diagram manager with cache.
25
+ */
26
+ export class MermaidManager implements IMermaidManager {
27
+ protected _diagrams: LruCache<string, HTMLElement>;
28
+ protected _themes: IThemeManager | null;
29
+
30
+ constructor(options: MermaidManager.IOptions = {}) {
31
+ this._diagrams = new LruCache({ maxSize: options.maxCacheSize || null });
32
+
33
+ // handle reacting to themes
34
+ if (options.themes) {
35
+ Private.initThemes(options.themes || null);
36
+ options.themes.themeChanged.connect(this.initialize, this);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Handle (re)-initializing mermaid based on external values.
42
+ */
43
+ initialize() {
44
+ this._diagrams.clear();
45
+ Private.initMermaid();
46
+ }
47
+
48
+ /**
49
+ * Get the underlying, potentially un-initialized mermaid module.
50
+ */
51
+ async getMermaid(): Promise<typeof MermaidType> {
52
+ return await Private.ensureMermaid();
53
+ }
54
+
55
+ /**
56
+ * Get the version of the currently-loaded mermaid module
57
+ */
58
+ getMermaidVersion(): string | null {
59
+ return Private.version();
60
+ }
61
+
62
+ /**
63
+ * Get a pre-cached mermaid figure.
64
+ *
65
+ * This primarily exists for the needs of `marked`, which supports async node
66
+ * visitors, but not async rendering.
67
+ */
68
+ getCachedFigure(text: string): HTMLElement | null {
69
+ return this._diagrams.get(text);
70
+ }
71
+
72
+ /**
73
+ * Attempt a raw rendering of mermaid to an SVG string, extracting some metadata.
74
+ */
75
+ async renderSvg(text: string): Promise<IMermaidManager.IRenderInfo> {
76
+ const _mermaid = await this.getMermaid();
77
+
78
+ const id = `jp-mermaid-${Private.nextMermaidId()}`;
79
+
80
+ // create temporary element into which to render
81
+ const el = document.createElement('div');
82
+ document.body.appendChild(el);
83
+ try {
84
+ const { svg } = await _mermaid.render(id, text, el);
85
+ const parser = new DOMParser();
86
+ const doc = parser.parseFromString(svg, 'image/svg+xml');
87
+
88
+ const info: IMermaidManager.IRenderInfo = { text, svg };
89
+ const svgEl = doc.querySelector('svg');
90
+ const { maxWidth } = svgEl?.style || {};
91
+ info.width = maxWidth ? parseFloat(maxWidth) : null;
92
+ const firstTitle = doc.querySelector('title');
93
+ const firstDesc = doc.querySelector('desc');
94
+ if (firstTitle) {
95
+ info.accessibleTitle = firstTitle.textContent;
96
+ }
97
+ if (firstDesc) {
98
+ info.accessibleDescription = firstDesc.textContent;
99
+ }
100
+ return info;
101
+ } finally {
102
+ el.remove();
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Provide and cache a fully-rendered element, checking the cache first.
108
+ */
109
+ async renderFigure(text: string): Promise<HTMLElement> {
110
+ // bail if already cached
111
+ let output: HTMLElement | null = this._diagrams.get(text);
112
+
113
+ if (output != null) {
114
+ return output;
115
+ }
116
+
117
+ let className = MERMAID_CLASS;
118
+
119
+ let result: HTMLElement | null = null;
120
+
121
+ // the element that will be returned
122
+ output = document.createElement('div');
123
+ output.className = className;
124
+
125
+ try {
126
+ const response = await this.renderSvg(text);
127
+ result = this.makeMermaidFigure(response);
128
+ } catch (err) {
129
+ output.classList.add(WARNING_CLASS);
130
+ result = await this.makeMermaidError(text);
131
+ }
132
+
133
+ let version = this.getMermaidVersion();
134
+
135
+ if (version) {
136
+ result.dataset.jpMermaidVersion = version;
137
+ }
138
+
139
+ output.appendChild(result);
140
+
141
+ // update the cache for use when rendering synchronously
142
+ this._diagrams.set(text, output);
143
+
144
+ return output;
145
+ }
146
+
147
+ /**
148
+ * Provide a code block with the mermaid source.
149
+ */
150
+ makeMermaidCode(text: string): HTMLElement {
151
+ // append the source
152
+ const pre = document.createElement('pre');
153
+ const code = document.createElement('code');
154
+ code.innerText = text;
155
+ pre.appendChild(code);
156
+ code.className = MERMAID_CODE_CLASS;
157
+ code.textContent = text;
158
+ return pre;
159
+ }
160
+
161
+ /**
162
+ * Get the parser message element from a failed parse.
163
+ *
164
+ * This doesn't do much of anything if the text is successfully parsed.
165
+ */
166
+ async makeMermaidError(text: string): Promise<HTMLElement> {
167
+ const _mermaid = await this.getMermaid();
168
+ let errorMessage = '';
169
+ try {
170
+ await _mermaid.parse(text);
171
+ } catch (err) {
172
+ errorMessage = `${err}`;
173
+ }
174
+
175
+ const result = document.createElement('details');
176
+ result.className = DETAILS_CLASS;
177
+ const summary = document.createElement('summary');
178
+ summary.className = SUMMARY_CLASS;
179
+ summary.appendChild(this.makeMermaidCode(text));
180
+ result.appendChild(summary);
181
+
182
+ const warning = document.createElement('pre');
183
+ warning.innerText = errorMessage;
184
+ result.appendChild(warning);
185
+ return result;
186
+ }
187
+
188
+ /**
189
+ * Extract extra attributes to add to a generated figure.
190
+ */
191
+ makeMermaidFigure(info: IMermaidManager.IRenderInfo): HTMLElement {
192
+ const figure = document.createElement('figure');
193
+ const img = document.createElement('img');
194
+
195
+ figure.appendChild(img);
196
+ img.setAttribute(
197
+ 'src',
198
+ `data:image/svg+xml,${encodeURIComponent(info.svg)}`
199
+ );
200
+
201
+ // add dimension information
202
+ if (info.width) {
203
+ img.width = info.width;
204
+ }
205
+
206
+ // add accessible alt title
207
+ if (info.accessibleTitle) {
208
+ img.setAttribute('alt', info.accessibleTitle);
209
+ }
210
+
211
+ figure.appendChild(this.makeMermaidCode(info.text));
212
+
213
+ // add accessible caption, with fallback to raw mermaid source
214
+ if (info.accessibleDescription) {
215
+ const caption = document.createElement('figcaption');
216
+ caption.className = 'sr-only';
217
+ caption.textContent = info.accessibleDescription;
218
+ figure.appendChild(caption);
219
+ }
220
+
221
+ return figure;
222
+ }
223
+ }
224
+
225
+ /**
226
+ * A namespace for implementation-specific details of this mermaid manager.
227
+ */
228
+ export namespace MermaidManager {
229
+ /**
230
+ * Initialization options for the mermaid manager.
231
+ */
232
+ export interface IOptions {
233
+ maxCacheSize?: number | null;
234
+ themes?: IThemeManager | null;
235
+ }
236
+ }
237
+
238
+ /**
239
+ * A namespace for global, private mermaid data.
240
+ */
241
+ namespace Private {
242
+ let _themes: IThemeManager | null = null;
243
+ let _mermaid: typeof MermaidType | null = null;
244
+ let _loading: PromiseDelegate<typeof MermaidType> | null = null;
245
+ let _nextMermaidId = 0;
246
+ let _version: string | null = null;
247
+
248
+ /**
249
+ * Cache a reference to the theme manager.
250
+ */
251
+ export function initThemes(themes: IThemeManager | null) {
252
+ _themes = themes;
253
+ }
254
+
255
+ /**
256
+ * Get the version of mermaid used for rendering.
257
+ */
258
+ export function version(): string | null {
259
+ return _version;
260
+ }
261
+
262
+ /**
263
+ * (Re-)initialize mermaid with lab-specific theme information
264
+ */
265
+ export function initMermaid(): boolean {
266
+ if (!_mermaid) {
267
+ return false;
268
+ }
269
+
270
+ let theme = MERMAID_DEFAULT_THEME;
271
+
272
+ if (_themes) {
273
+ const jpTheme = _themes.theme;
274
+ theme =
275
+ jpTheme && _themes.isLight(jpTheme)
276
+ ? MERMAID_DEFAULT_THEME
277
+ : MERMAID_DARK_THEME;
278
+ }
279
+
280
+ const fontFamily = window
281
+ .getComputedStyle(document.body)
282
+ .getPropertyValue('--jp-ui-font-family');
283
+
284
+ _mermaid.mermaidAPI.globalReset();
285
+ _mermaid.mermaidAPI.initialize({
286
+ theme,
287
+ fontFamily,
288
+ maxTextSize: 100000,
289
+ startOnLoad: false
290
+ });
291
+ return true;
292
+ }
293
+
294
+ /**
295
+ * Determine whether mermaid has been loaded yet.
296
+ */
297
+ export function getMermaid(): typeof MermaidType | null {
298
+ return _mermaid;
299
+ }
300
+
301
+ /**
302
+ * Provide a globally-unique, but unstable, ID for disambiguation.
303
+ */
304
+ export function nextMermaidId() {
305
+ return _nextMermaidId++;
306
+ }
307
+
308
+ /**
309
+ * Ensure mermaid has been lazily loaded once, initialized, and cached.
310
+ */
311
+ export async function ensureMermaid(): Promise<typeof MermaidType> {
312
+ if (_mermaid != null) {
313
+ return _mermaid;
314
+ }
315
+ if (_loading) {
316
+ return _loading.promise;
317
+ }
318
+ _loading = new PromiseDelegate();
319
+ _version = (await import('mermaid/package.json')).version;
320
+ _mermaid = (await import('mermaid')).default;
321
+ initMermaid();
322
+ _loading.resolve(_mermaid);
323
+ return _mermaid;
324
+ }
325
+ }
@@ -0,0 +1,48 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ import { IMermaidManager, IMermaidMarkdown } from './tokens';
5
+
6
+ /**
7
+ * An implementation of mermaid fenced code blocks in markdown.
8
+ */
9
+ export class MermaidMarkdown implements IMermaidMarkdown {
10
+ protected _mermaid: IMermaidManager;
11
+ readonly languages = ['mermaid'];
12
+ readonly rank = 100;
13
+
14
+ constructor(options: MermaidMarkdown.IOptions) {
15
+ this._mermaid = options.mermaid;
16
+ }
17
+
18
+ /**
19
+ * Pre-parse and cache the rendered text.
20
+ */
21
+ async walk(text: string): Promise<void> {
22
+ await this._mermaid.renderFigure(text);
23
+ }
24
+
25
+ /**
26
+ * Render the diagram.
27
+ */
28
+ render(text: string): string | null {
29
+ // handle pre-cached mermaid figures
30
+ let cachedFigure: HTMLElement | null = this._mermaid.getCachedFigure(text);
31
+ if (cachedFigure) {
32
+ return cachedFigure.outerHTML;
33
+ }
34
+ return null;
35
+ }
36
+ }
37
+
38
+ /**
39
+ * A namespace for mermaid markdown
40
+ */
41
+ export namespace MermaidMarkdown {
42
+ /**
43
+ * Initialization options for mermaid markdown
44
+ */
45
+ export interface IOptions {
46
+ mermaid: IMermaidManager;
47
+ }
48
+ }
package/src/mime.ts ADDED
@@ -0,0 +1,118 @@
1
+ /* -----------------------------------------------------------------------------
2
+ | Copyright (c) Jupyter Development Team.
3
+ | Distributed under the terms of the Modified BSD License.
4
+ |----------------------------------------------------------------------------*/
5
+ /**
6
+ * @packageDocumentation
7
+ * @module mermaid-extension
8
+ */
9
+
10
+ import {
11
+ IMermaidManager,
12
+ MERMAID_CLASS,
13
+ MERMAID_MIME_TYPE,
14
+ WARNING_CLASS
15
+ } from './tokens';
16
+ import { IRenderMime } from '@jupyterlab/rendermime-interfaces';
17
+ import { PromiseDelegate } from '@lumino/coreutils';
18
+ import { Widget } from '@lumino/widgets';
19
+
20
+ const SVG_MIME = 'image/svg+xml';
21
+
22
+ /**
23
+ * A widget for rendering mermaid text-based diagrams, for usage with rendermime.
24
+ */
25
+ export class RenderedMermaid extends Widget implements IRenderMime.IRenderer {
26
+ protected static _manager: IMermaidManager | null = null;
27
+ protected static _managerReady = new PromiseDelegate<IMermaidManager>();
28
+ protected _lastRendered: string | null = null;
29
+
30
+ /**
31
+ * Create a new widget for rendering Vega/Vega-Lite.
32
+ */
33
+ constructor(options: IRenderMime.IRendererOptions) {
34
+ super();
35
+ this._mimeType = options.mimeType;
36
+ this.addClass(MERMAID_CLASS);
37
+ }
38
+
39
+ static set manager(manager: IMermaidManager) {
40
+ if (RenderedMermaid._manager) {
41
+ console.warn('Mermaid manager may only be set once, and is already set.');
42
+ return;
43
+ }
44
+ RenderedMermaid._manager = manager;
45
+ RenderedMermaid._managerReady.resolve(manager);
46
+ }
47
+
48
+ /**
49
+ * Render mermaid text-based diagrams into this widget's node.
50
+ */
51
+ async renderModel(model: IRenderMime.IMimeModel): Promise<void> {
52
+ const manager = await RenderedMermaid._managerReady.promise;
53
+
54
+ const text = model.data[this._mimeType] as string | undefined;
55
+ if (text == null || text === this._lastRendered) {
56
+ return;
57
+ }
58
+
59
+ this._lastRendered = text;
60
+
61
+ // get a div containing a figure or parser message
62
+ const figure = await manager.renderFigure(text);
63
+
64
+ if (figure.classList.contains(WARNING_CLASS)) {
65
+ this.node.classList.add(WARNING_CLASS);
66
+ } else {
67
+ this.node.classList.remove(WARNING_CLASS);
68
+ }
69
+
70
+ if (!figure.firstChild) {
71
+ return;
72
+ }
73
+
74
+ if (this.node.innerHTML !== figure.innerHTML) {
75
+ this.node.innerHTML = figure.innerHTML;
76
+ }
77
+
78
+ // capture the version of mermaid used
79
+ const version = manager.getMermaidVersion();
80
+ const mermaidMetadata = {
81
+ ...((model.metadata[MERMAID_MIME_TYPE] as Record<string, any>) || {}),
82
+ version
83
+ };
84
+ const metadata = {
85
+ ...model.metadata,
86
+ [MERMAID_MIME_TYPE]: mermaidMetadata
87
+ };
88
+
89
+ // if available, set the fully-rendered SVG
90
+ const img = figure.querySelector('img');
91
+
92
+ if (img) {
93
+ const svg = decodeURIComponent(img.src.split(',')[1]);
94
+ const oldSvg = model.data[SVG_MIME];
95
+ if (svg !== oldSvg) {
96
+ model.setData({
97
+ data: { ...model.data, [SVG_MIME]: svg },
98
+ metadata
99
+ });
100
+ }
101
+ } else {
102
+ const dataWithoutSvg = { ...model.data };
103
+ delete dataWithoutSvg[SVG_MIME];
104
+ model.setData({ data: dataWithoutSvg, metadata });
105
+ }
106
+ }
107
+
108
+ private _mimeType: string;
109
+ }
110
+
111
+ /**
112
+ * A mime renderer factory for mermaid text-based diagrams.
113
+ */
114
+ export const rendererFactory: IRenderMime.IRendererFactory = {
115
+ safe: true,
116
+ mimeTypes: [MERMAID_MIME_TYPE],
117
+ createRenderer: options => new RenderedMermaid(options)
118
+ };
package/src/tokens.ts ADDED
@@ -0,0 +1,112 @@
1
+ // Copyright (c) Jupyter Development Team.
2
+ // Distributed under the terms of the Modified BSD License.
3
+
4
+ import { Token } from '@lumino/coreutils';
5
+ import type MermaidType from 'mermaid';
6
+
7
+ // documented upstream constants
8
+ export const MERMAID_MIME_TYPE = 'text/vnd.mermaid';
9
+ export const MERMAID_FILE_EXTENSIONS = ['.mmd', '.mermaid'];
10
+
11
+ // mermaid themes
12
+ export const MERMAID_DEFAULT_THEME = 'default';
13
+ export const MERMAID_DARK_THEME = 'dark';
14
+
15
+ // DOM
16
+ export const MERMAID_CLASS = 'jp-RenderedMermaid';
17
+ export const MERMAID_CODE_CLASS = 'mermaid';
18
+ export const WARNING_CLASS = 'jp-mod-warning';
19
+ export const DETAILS_CLASS = 'jp-RenderedMermaid-Details';
20
+ export const SUMMARY_CLASS = 'jp-RenderedMermaid-Summary';
21
+
22
+ /**
23
+ * The exported token for a mermaid manager
24
+ */
25
+ export const IMermaidManager = new Token<IMermaidManager>(
26
+ '@jupyterlab/mermaid:IMermaidManager',
27
+ `a manager for rendering mermaid text-based diagrams`
28
+ );
29
+
30
+ /**
31
+ * A namespace for public mermaid interfaces.
32
+ */
33
+ export interface IMermaidManager {
34
+ /**
35
+ * Get the (potentially uninitialized) mermaid module.
36
+ */
37
+ getMermaid(): Promise<typeof MermaidType>;
38
+
39
+ /**
40
+ * Get the version of the currently-loaded mermaid module
41
+ */
42
+ getMermaidVersion(): string | null;
43
+
44
+ /**
45
+ * Render mermaid source to an SVG string with extraced metadata.
46
+ */
47
+ renderSvg(text: string): Promise<IMermaidManager.IRenderInfo>;
48
+
49
+ /**
50
+ * Render and cache mermaid source as a figure of an image, or a unsuccessful parser message.
51
+ */
52
+ renderFigure(text: string): Promise<HTMLElement>;
53
+
54
+ /**
55
+ * Get the pre-cached element for a mermaid string, if available.
56
+ */
57
+ getCachedFigure(text: string): HTMLElement | null;
58
+ }
59
+
60
+ /**
61
+ * A namespace for the mermaid manager.
62
+ */
63
+ export namespace IMermaidManager {
64
+ /**
65
+ * The results of a successful rendering of a mermaid text-based diagram.
66
+ */
67
+ export interface IRenderInfo {
68
+ /** the original source of the diagram. */
69
+ text: string;
70
+ /** The raw rendered SVG. */
71
+ svg: string;
72
+ /** The extracted accessible description, if found. */
73
+ accessibleDescription?: string | null;
74
+ /** The extracted accessible title, if found. */
75
+ accessibleTitle?: string | null;
76
+ /** The extracted width of the digaram, if found. */
77
+ width?: number | null;
78
+ }
79
+ }
80
+
81
+ /**
82
+ * The exported token for a mermaid manager
83
+ */
84
+ export const IMermaidMarkdown = new Token<IMermaidMarkdown>(
85
+ '@jupyterlab/mermaid:IMermaidMarkdown',
86
+ `a manager for rendering mermaid text-based diagrams in markdown fenced code blocks`
87
+ );
88
+
89
+ /**
90
+ * A handler for mermaid fenced code blocks in markdown
91
+ *
92
+ * This duplicates the (currently) private `IFencedBlockRenderer` in
93
+ * `@jupyterlab/markedparser-extension`.
94
+ */
95
+ export interface IMermaidMarkdown {
96
+ /**
97
+ * The languages this block accepts.
98
+ */
99
+ languages: string[];
100
+ /**
101
+ * The order in which the block would be processed
102
+ */
103
+ rank: number;
104
+ /**
105
+ * Handle up-front loading/parsing mermaid
106
+ */
107
+ walk: (text: string) => Promise<void>;
108
+ /**
109
+ * Provide pre-rendered diagram content
110
+ */
111
+ render: (text: string) => string | null;
112
+ }