@quarto/jupyterlab-quarto 0.1.45 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (188) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +48 -15
  3. package/lib/__tests__/jupyterlab_quarto.spec.d.ts +3 -0
  4. package/lib/__tests__/jupyterlab_quarto.spec.js +9 -0
  5. package/lib/ast/ast.d.ts +1 -2
  6. package/lib/ast/ast.js +4 -3
  7. package/lib/const.d.ts +1 -2
  8. package/lib/const.js +5 -6
  9. package/lib/hooks/codemirror.d.ts +5 -4
  10. package/lib/hooks/codemirror.js +37 -12
  11. package/lib/index.d.ts +2 -3
  12. package/lib/index.js +6 -5
  13. package/lib/manager.d.ts +2 -2
  14. package/lib/manager.js +14 -16
  15. package/lib/plugins/callouts.d.ts +1 -2
  16. package/lib/plugins/callouts.js +59 -58
  17. package/lib/plugins/cites.d.ts +1 -2
  18. package/lib/plugins/cites.js +41 -23
  19. package/lib/plugins/decorator.d.ts +1 -2
  20. package/lib/plugins/decorator.js +11 -12
  21. package/lib/plugins/divs.d.ts +1 -2
  22. package/lib/plugins/divs.js +20 -9
  23. package/lib/plugins/figure-divs.d.ts +1 -2
  24. package/lib/plugins/figure-divs.js +18 -17
  25. package/lib/plugins/figures.d.ts +3 -4
  26. package/lib/plugins/figures.js +30 -31
  27. package/lib/plugins/gridtables/common/gridtables/GetCells.d.ts +5 -6
  28. package/lib/plugins/gridtables/common/gridtables/GetCells.js +6 -8
  29. package/lib/plugins/gridtables/common/gridtables/GetColumnWidths.d.ts +5 -6
  30. package/lib/plugins/gridtables/common/gridtables/GetColumnWidths.js +9 -14
  31. package/lib/plugins/gridtables/common/markdown-it/ColumnAlignments.d.ts +0 -1
  32. package/lib/plugins/gridtables/common/markdown-it/ColumnAlignments.js +0 -1
  33. package/lib/plugins/gridtables/common/markdown-it/EmitTable.d.ts +3 -4
  34. package/lib/plugins/gridtables/common/markdown-it/EmitTable.js +12 -15
  35. package/lib/plugins/gridtables/common/markdown-it/GetCharCodeAtStartOfLine.d.ts +1 -2
  36. package/lib/plugins/gridtables/common/markdown-it/GetCharCodeAtStartOfLine.js +1 -3
  37. package/lib/plugins/gridtables/common/markdown-it/GetLine.d.ts +1 -2
  38. package/lib/plugins/gridtables/common/markdown-it/GetLine.js +0 -1
  39. package/lib/plugins/gridtables/common/markdown-it/ParseTable.d.ts +2 -3
  40. package/lib/plugins/gridtables/common/markdown-it/ParseTable.js +18 -28
  41. package/lib/plugins/gridtables/common/markdown-it/ParseTableResult.d.ts +1 -2
  42. package/lib/plugins/gridtables/common/markdown-it/ParseTableResult.js +0 -1
  43. package/lib/plugins/gridtables/index.d.ts +0 -1
  44. package/lib/plugins/gridtables/index.js +2 -3
  45. package/lib/plugins/gridtables/interfaces/markdown-it/IState.d.ts +1 -2
  46. package/lib/plugins/gridtables/interfaces/markdown-it/IState.js +0 -1
  47. package/lib/plugins/gridtables/interfaces/markdown-it/IToken.d.ts +0 -1
  48. package/lib/plugins/gridtables/interfaces/markdown-it/IToken.js +0 -1
  49. package/lib/plugins/gridtables/interfaces/markdown-it/TRuleFunction.d.ts +1 -2
  50. package/lib/plugins/gridtables/interfaces/markdown-it/TRuleFunction.js +0 -1
  51. package/lib/plugins/gridtables/rules/gridtable.d.ts +2 -3
  52. package/lib/plugins/gridtables/rules/gridtable.js +5 -6
  53. package/lib/plugins/index.d.ts +15 -0
  54. package/lib/plugins/index.js +21 -0
  55. package/lib/plugins/math.d.ts +4 -3
  56. package/lib/plugins/math.js +33 -31
  57. package/lib/plugins/mermaid/index.d.ts +1 -2
  58. package/lib/plugins/mermaid/index.js +19 -14
  59. package/lib/plugins/shortcodes.d.ts +1 -2
  60. package/lib/plugins/shortcodes.js +6 -7
  61. package/lib/plugins/spans.d.ts +1 -2
  62. package/lib/plugins/spans.js +2 -4
  63. package/lib/plugins/table-captions.d.ts +1 -2
  64. package/lib/plugins/table-captions.js +19 -16
  65. package/lib/plugins/utils/html.d.ts +1 -2
  66. package/lib/plugins/utils/html.js +19 -15
  67. package/lib/plugins/utils/markdownit.d.ts +0 -1
  68. package/lib/plugins/utils/markdownit.js +14 -13
  69. package/lib/plugins/utils/tok.d.ts +0 -1
  70. package/lib/plugins/utils/tok.js +12 -13
  71. package/lib/plugins/yaml.d.ts +1 -2
  72. package/lib/plugins/yaml.js +59 -49
  73. package/lib/providers/attrs.d.ts +1 -2
  74. package/lib/providers/attrs.js +5 -6
  75. package/lib/providers/callouts.d.ts +1 -2
  76. package/lib/providers/callouts.js +7 -8
  77. package/lib/providers/cites.d.ts +1 -2
  78. package/lib/providers/cites.js +7 -8
  79. package/lib/providers/decorator.d.ts +1 -2
  80. package/lib/providers/decorator.js +7 -8
  81. package/lib/providers/deflist.d.ts +1 -2
  82. package/lib/providers/deflist.js +5 -6
  83. package/lib/providers/divs.d.ts +1 -2
  84. package/lib/providers/divs.js +9 -10
  85. package/lib/providers/figure-divs.d.ts +1 -2
  86. package/lib/providers/figure-divs.js +5 -6
  87. package/lib/providers/figures.d.ts +1 -2
  88. package/lib/providers/figures.js +5 -6
  89. package/lib/providers/footnotes.d.ts +1 -2
  90. package/lib/providers/footnotes.js +5 -6
  91. package/lib/providers/gridtables.d.ts +1 -2
  92. package/lib/providers/gridtables.js +5 -6
  93. package/lib/providers/math.d.ts +1 -2
  94. package/lib/providers/math.js +12 -13
  95. package/lib/providers/mermaid.d.ts +1 -2
  96. package/lib/providers/mermaid.js +10 -9
  97. package/lib/providers/provider.d.ts +1 -2
  98. package/lib/providers/provider.js +0 -1
  99. package/lib/providers/shortcodes.d.ts +1 -2
  100. package/lib/providers/shortcodes.js +5 -6
  101. package/lib/providers/spans.d.ts +1 -2
  102. package/lib/providers/spans.js +8 -9
  103. package/lib/providers/sub.d.ts +1 -2
  104. package/lib/providers/sub.js +5 -6
  105. package/lib/providers/sup.d.ts +1 -2
  106. package/lib/providers/sup.js +5 -6
  107. package/lib/providers/table-captions.d.ts +1 -2
  108. package/lib/providers/table-captions.js +5 -6
  109. package/lib/providers/tasklists.d.ts +1 -2
  110. package/lib/providers/tasklists.js +5 -6
  111. package/lib/providers/yaml.d.ts +1 -2
  112. package/lib/providers/yaml.js +7 -8
  113. package/lib/types.d.ts +0 -1
  114. package/lib/types.js +0 -1
  115. package/lib/widgets.d.ts +0 -1
  116. package/lib/widgets.js +5 -6
  117. package/package.json +105 -39
  118. package/style/base.css +34 -33
  119. package/style/index.css +1 -1
  120. package/lib/__tests__/index.spec.d.ts +0 -6
  121. package/lib/__tests__/index.spec.js +0 -61
  122. package/lib/__tests__/index.spec.js.map +0 -1
  123. package/lib/__tests__/myextension.spec.d.ts +0 -6
  124. package/lib/__tests__/myextension.spec.js +0 -11
  125. package/lib/__tests__/myextension.spec.js.map +0 -1
  126. package/lib/ast/ast.js.map +0 -1
  127. package/lib/const.js.map +0 -1
  128. package/lib/hooks/codemirror.js.map +0 -1
  129. package/lib/index.js.map +0 -1
  130. package/lib/manager.js.map +0 -1
  131. package/lib/plugins/callouts.js.map +0 -1
  132. package/lib/plugins/cites.js.map +0 -1
  133. package/lib/plugins/decorator.js.map +0 -1
  134. package/lib/plugins/divs.js.map +0 -1
  135. package/lib/plugins/figure-divs.js.map +0 -1
  136. package/lib/plugins/figures.js.map +0 -1
  137. package/lib/plugins/gridtables/common/gridtables/GetCells.js.map +0 -1
  138. package/lib/plugins/gridtables/common/gridtables/GetColumnWidths.js.map +0 -1
  139. package/lib/plugins/gridtables/common/markdown-it/ColumnAlignments.js.map +0 -1
  140. package/lib/plugins/gridtables/common/markdown-it/EmitTable.js.map +0 -1
  141. package/lib/plugins/gridtables/common/markdown-it/GetCharCodeAtStartOfLine.js.map +0 -1
  142. package/lib/plugins/gridtables/common/markdown-it/GetLine.js.map +0 -1
  143. package/lib/plugins/gridtables/common/markdown-it/ParseTable.js.map +0 -1
  144. package/lib/plugins/gridtables/common/markdown-it/ParseTableResult.js.map +0 -1
  145. package/lib/plugins/gridtables/index.js.map +0 -1
  146. package/lib/plugins/gridtables/interfaces/markdown-it/IState.js.map +0 -1
  147. package/lib/plugins/gridtables/interfaces/markdown-it/IToken.js.map +0 -1
  148. package/lib/plugins/gridtables/interfaces/markdown-it/TRuleFunction.js.map +0 -1
  149. package/lib/plugins/gridtables/rules/gridtable.js.map +0 -1
  150. package/lib/plugins/math.js.map +0 -1
  151. package/lib/plugins/mermaid/index.js.map +0 -1
  152. package/lib/plugins/shortcodes.js.map +0 -1
  153. package/lib/plugins/spans.js.map +0 -1
  154. package/lib/plugins/table-captions.js.map +0 -1
  155. package/lib/plugins/utils/html.js.map +0 -1
  156. package/lib/plugins/utils/markdownit.js.map +0 -1
  157. package/lib/plugins/utils/tok.js.map +0 -1
  158. package/lib/plugins/yaml.js.map +0 -1
  159. package/lib/providers/attrs.js.map +0 -1
  160. package/lib/providers/callouts.js.map +0 -1
  161. package/lib/providers/cites.js.map +0 -1
  162. package/lib/providers/decorator.js.map +0 -1
  163. package/lib/providers/deflist.js.map +0 -1
  164. package/lib/providers/divs.js.map +0 -1
  165. package/lib/providers/figure-divs.js.map +0 -1
  166. package/lib/providers/figures.js.map +0 -1
  167. package/lib/providers/footnotes.js.map +0 -1
  168. package/lib/providers/gridtables.js.map +0 -1
  169. package/lib/providers/math.js.map +0 -1
  170. package/lib/providers/mermaid.js.map +0 -1
  171. package/lib/providers/provider.js.map +0 -1
  172. package/lib/providers/shortcodes.js.map +0 -1
  173. package/lib/providers/spans.js.map +0 -1
  174. package/lib/providers/sub.js.map +0 -1
  175. package/lib/providers/sup.js.map +0 -1
  176. package/lib/providers/table-captions.js.map +0 -1
  177. package/lib/providers/tasklists.js.map +0 -1
  178. package/lib/providers/yaml.js.map +0 -1
  179. package/lib/types.js.map +0 -1
  180. package/lib/widgets.js.map +0 -1
  181. package/schema/plugin.json +0 -8
  182. package/src/@types/markdown-it-deflist.d.ts +0 -10
  183. package/src/@types/markdown-it-footnote.d.ts +0 -10
  184. package/src/@types/markdown-it-gridtables.d.ts +0 -10
  185. package/src/@types/markdown-it-implicit-figures.d.ts +0 -10
  186. package/src/@types/markdown-it-sub.d.ts +0 -10
  187. package/src/@types/markdown-it-sup.d.ts +0 -10
  188. package/src/@types/markdown-it-task-lists.d.ts +0 -10
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2023, Posit, PBC
3
+ Copyright (c) 2023, Charles Teague
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
package/README.md CHANGED
@@ -1,23 +1,34 @@
1
1
  # JupyterLab Quarto Extension
2
2
 
3
- [Quarto](https://www.quarto.org) is an open source project that combines Jupyter notebooks with flexible options to use a single source document to produce high-quality articles, reports, presentations, websites, and books in HTML, PDF, MS Word, ePub, and more. Quarto supports a wide variety of useful new features useful in technical documents, including support for LaTeX equations, citations, cross-references, figure panels, callouts, advanced page layout, and more.
3
+ [Quarto](https://www.quarto.org) is an open source project that combines Jupyter notebooks with flexible options to use a single source document to produce high-quality articles, reports, presentations, websites, and books in HTML, PDF, MS Word, ePub, and more. Quarto supports a wide variety of useful new features useful in technical documents, including support for LaTeX equations, citations, cross-references, figure panels, callouts, advanced page layout, and more.
4
4
 
5
5
  The JupyterLab Quarto extension allows JupyterLab to render notebooks which include Quarto markdown content.
6
6
  <br/><br/>
7
+
7
8
  <p align="center">
8
9
  <img src="https://user-images.githubusercontent.com/261654/230087634-d5027ebc-8508-43b4-81c9-c4b7d6cfa738.png" width="60%">
9
10
  </p>
10
11
 
12
+ ### Binder
13
+
14
+ You can try an example of the extension in a notebook (though you can't actually render the notebook using Quarto) on Binder.
15
+
16
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/quarto-dev/jupyterlab-quarto/main?urlpath=lab)
17
+
18
+ ## Status
19
+
20
+ [![Github Actions Status](https://github.com/quarto-dev/jupyterlab-quarto/workflows/Build/badge.svg)](https://github.com/quarto-dev/jupyterlab-quarto/actions/workflows/build.yml)
21
+
11
22
  ## Requirements
12
23
 
13
- - JupyterLab >= 3.0
24
+ - JupyterLab >= 4.0.0
14
25
 
15
26
  ## Install
16
27
 
17
28
  To install the extension, execute:
18
29
 
19
30
  ```bash
20
- pip install jupyterlab-quarto
31
+ pip install jupyterlab_quarto
21
32
  ```
22
33
 
23
34
  ## Uninstall
@@ -25,40 +36,42 @@ pip install jupyterlab-quarto
25
36
  To remove the extension, execute:
26
37
 
27
38
  ```bash
28
- pip uninstall jupyterlab-quarto
39
+ pip uninstall jupyterlab_quarto
29
40
  ```
30
41
 
31
42
  ## Contributing
32
43
 
33
44
  ### Development install
34
45
 
46
+ Note: You will need NodeJS to build the extension package.
47
+
48
+ The `jlpm` command is JupyterLab's pinned version of
49
+ [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
50
+ `yarn` or `npm` in lieu of `jlpm` below.
51
+
35
52
  ```bash
36
- # From apps/jupyterlab
53
+ # Clone the repo to your local environment
54
+ # Change directory to the jupyterlab_quarto directory
37
55
  # Install package in development mode
38
56
  pip install -e "."
39
57
  # Link your development version of the extension with JupyterLab
40
58
  jupyter labextension develop . --overwrite
41
59
  # Rebuild extension Typescript source after making changes
42
- yarn build
60
+ jlpm build
43
61
  ```
44
- Note: You will need NodeJS to build the extension package.
45
-
46
- Note: The `jlpm` command is JupyterLab's pinned version of
47
- [yarn](https://yarnpkg.com/) that is installed with JupyterLab. You may use
48
- `yarn` or `npm` in lieu of `jlpm` below.
49
62
 
50
63
  You can watch the source directory and run JupyterLab at the same time in different terminals to watch for changes in the extension's source and automatically rebuild the extension.
51
64
 
52
65
  ```bash
53
66
  # Watch the source directory in one terminal, automatically rebuilding when needed
54
- yarn watch
67
+ jlpm watch
55
68
  # Run JupyterLab in another terminal
56
69
  jupyter lab
57
70
  ```
58
71
 
59
72
  With the watch command running, every saved change will immediately be built locally and available in your running JupyterLab. Refresh JupyterLab to load the change in your browser (you may need to wait several seconds for the extension to be rebuilt).
60
73
 
61
- By default, the `build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:
74
+ By default, the `jlpm build` command generates the source maps for this extension to make it easier to debug using the browser dev tools. To also generate source maps for the JupyterLab core extensions, you can run the following command:
62
75
 
63
76
  ```bash
64
77
  jupyter lab build --minimize=False
@@ -67,12 +80,32 @@ jupyter lab build --minimize=False
67
80
  ### Development uninstall
68
81
 
69
82
  ```bash
70
- pip uninstall jupyterlab-quarto
83
+ pip uninstall jupyterlab_quarto
71
84
  ```
72
85
 
73
86
  In development mode, you will also need to remove the symlink created by `jupyter labextension develop`
74
87
  command. To find its location, you can run `jupyter labextension list` to figure out where the `labextensions`
75
- folder is located. Then you can remove the symlink named `jupyterlab-quarto` within that folder.
88
+ folder is located. Then you can remove the symlink named `@quarto/jupyterlab-quarto` within that folder.
89
+
90
+ ### Testing the extension
91
+
92
+ #### Frontend tests
93
+
94
+ This extension is using [Jest](https://jestjs.io/) for JavaScript code testing.
95
+
96
+ To execute them, execute:
97
+
98
+ ```sh
99
+ jlpm
100
+ jlpm test
101
+ ```
102
+
103
+ #### Integration tests
104
+
105
+ This extension uses [Playwright](https://playwright.dev/) for the integration tests (aka user level tests).
106
+ More precisely, the JupyterLab helper [Galata](https://github.com/jupyterlab/jupyterlab/tree/master/galata) is used to handle testing the extension in JupyterLab.
107
+
108
+ More information are provided within the [ui-tests](./ui-tests/README.md) README.
76
109
 
77
110
  ### Packaging the extension
78
111
 
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Example of [Jest](https://jestjs.io/docs/getting-started) unit tests
3
+ */
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Example of [Jest](https://jestjs.io/docs/getting-started) unit tests
4
+ */
5
+ describe('@quarto/jupyterlab-quarto', () => {
6
+ it('should be tested', () => {
7
+ expect(1 + 1).toEqual(2);
8
+ });
9
+ });
package/lib/ast/ast.d.ts CHANGED
@@ -1,3 +1,2 @@
1
- import type Token from "markdown-it/lib/token";
1
+ import type Token from 'markdown-it/lib/token';
2
2
  export declare const toAst: (toks: Token[]) => Token[];
3
- //# sourceMappingURL=ast.d.ts.map
package/lib/ast/ast.js CHANGED
@@ -1,8 +1,9 @@
1
1
  export const toAst = (toks) => {
2
2
  let pos = 0;
3
3
  const inner = () => {
4
- if (pos >= toks.length)
4
+ if (pos >= toks.length) {
5
5
  return;
6
+ }
6
7
  const tok = toks[pos];
7
8
  if (tok.type.endsWith('_open')) {
8
9
  ++pos;
@@ -31,9 +32,9 @@ export const toAst = (toks) => {
31
32
  const result = [];
32
33
  while (pos < toks.length) {
33
34
  const node = inner();
34
- if (node)
35
+ if (node) {
35
36
  result.push(node);
37
+ }
36
38
  }
37
39
  return result;
38
40
  };
39
- //# sourceMappingURL=ast.js.map
package/lib/const.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Token } from '@lumino/coreutils';
2
- import { MarkdownItManager } from "./types";
2
+ import { MarkdownItManager } from './types';
3
3
  export declare const kPackageNamespace = "jupyterlab-quarto";
4
4
  export declare const kMarkdownItMgr: Token<MarkdownItManager>;
5
- //# sourceMappingURL=const.d.ts.map
package/lib/const.js CHANGED
@@ -1,12 +1,11 @@
1
1
  /*
2
- * const.ts
3
- *
4
- * Copyright (C) 2020-2023 Posit Software, PBC
5
- *
6
- */
2
+ * const.ts
3
+ *
4
+ * Copyright (C) 2020-2023 Posit Software, PBC
5
+ *
6
+ */
7
7
  import { Token } from '@lumino/coreutils';
8
8
  // The namespace for this project
9
9
  export const kPackageNamespace = 'jupyterlab-quarto';
10
10
  // The MarkdownIt manager token.
11
11
  export const kMarkdownItMgr = new Token(kPackageNamespace);
12
- //# sourceMappingURL=const.js.map
@@ -1,4 +1,5 @@
1
- import { Hook } from "../types";
2
- export declare function codeMirrorPreloadHook(): Hook<string, string>;
3
- export declare const codeMirrorHighlight: (str: string, lang: string) => string;
4
- //# sourceMappingURL=codemirror.d.ts.map
1
+ import { Hook } from '../types';
2
+ import { IEditorLanguageRegistry } from '@jupyterlab/codemirror';
3
+ export declare function codeMirrorPreloadHook(registry: IEditorLanguageRegistry): Hook<string, string>;
4
+ export declare const codeMirrorHighlighter: (languageRegistry: IEditorLanguageRegistry) => (str: string, lang: string, _attr: any) => string;
5
+ export declare const codeMirrorHighlight: (str: string, lang: string, registry: IEditorLanguageRegistry) => string;
@@ -1,11 +1,10 @@
1
1
  /*
2
- * hooks.ts
3
- *
4
- * Copyright (C) 2020-2023 Posit Software, PBC
5
- *
6
- */
7
- import { Mode } from '@jupyterlab/codemirror';
8
- export function codeMirrorPreloadHook() {
2
+ * hooks.ts
3
+ *
4
+ * Copyright (C) 2020-2023 Posit Software, PBC
5
+ *
6
+ */
7
+ export function codeMirrorPreloadHook(registry) {
9
8
  // TODO: Properly deal with {r}, {{r}} style expressions
10
9
  const fenced = new RegExp(/^`{3}([^\s]+)/g);
11
10
  return {
@@ -14,7 +13,7 @@ export function codeMirrorPreloadHook() {
14
13
  let match;
15
14
  while ((match = fenced.exec(source))) {
16
15
  if (!newModes.has(match[1])) {
17
- newModes.set(match[1], Mode.ensure(match[1]));
16
+ newModes.set(match[1], registry.getLanguage(match[1]));
18
17
  }
19
18
  }
20
19
  if (newModes.size) {
@@ -24,19 +23,46 @@ export function codeMirrorPreloadHook() {
24
23
  }
25
24
  };
26
25
  }
27
- export const codeMirrorHighlight = (str, lang) => {
26
+ export const codeMirrorHighlighter = (languageRegistry) => {
27
+ return (str, lang, _attr) => {
28
+ if (!lang) {
29
+ return ''; // use external default escaping
30
+ }
31
+ try {
32
+ const spec = languageRegistry.findBest(lang);
33
+ if (!spec) {
34
+ console.warn(`No CodeMirror mode: ${lang}`);
35
+ return '';
36
+ }
37
+ const el = document.createElement('div');
38
+ try {
39
+ languageRegistry.highlight(str, spec, el);
40
+ return el.innerHTML;
41
+ }
42
+ catch (err) {
43
+ console.warn(`Failed to highlight ${lang} code`, err);
44
+ }
45
+ }
46
+ catch (err) {
47
+ console.warn(`No CodeMirror mode: ${lang}`);
48
+ console.warn(`Require CodeMirror mode error: ${err}`);
49
+ }
50
+ return '';
51
+ };
52
+ };
53
+ export const codeMirrorHighlight = (str, lang, registry) => {
28
54
  if (!lang) {
29
55
  return ''; // use external default escaping
30
56
  }
31
57
  try {
32
- const spec = Mode.findBest(lang);
58
+ const spec = registry.findBest(lang);
33
59
  if (!spec) {
34
60
  console.warn(`No CodeMirror mode: ${lang}`);
35
61
  return '';
36
62
  }
37
63
  const el = document.createElement('div');
38
64
  try {
39
- Mode.run(str, spec.mime, el);
65
+ registry.highlight(str, spec, el);
40
66
  return el.innerHTML;
41
67
  }
42
68
  catch (err) {
@@ -49,4 +75,3 @@ export const codeMirrorHighlight = (str, lang) => {
49
75
  }
50
76
  return '';
51
77
  };
52
- //# sourceMappingURL=codemirror.js.map
package/lib/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { JupyterFrontEnd, JupyterFrontEndPlugin } from '@jupyterlab/application';
1
+ import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  import { MarkdownItManager } from './types';
3
3
  import '../style/index.css';
4
- declare const _default: (JupyterFrontEndPlugin<void, JupyterFrontEnd.IShell, "desktop" | "mobile"> | JupyterFrontEndPlugin<MarkdownItManager, JupyterFrontEnd.IShell, "desktop" | "mobile">)[];
4
+ declare const _default: (JupyterFrontEndPlugin<void> | JupyterFrontEndPlugin<MarkdownItManager>)[];
5
5
  export default _default;
6
- //# sourceMappingURL=index.d.ts.map
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { IEditorLanguageRegistry, IEditorThemeRegistry } from '@jupyterlab/codemirror';
1
2
  import { mermaid } from './providers/mermaid';
2
3
  import { kMarkdownItMgr, kPackageNamespace } from './const';
3
4
  import { footnotes } from './providers/footnotes';
@@ -24,10 +25,11 @@ const plugin = {
24
25
  id: `${kPackageNamespace}:plugin`,
25
26
  autoStart: true,
26
27
  provides: kMarkdownItMgr,
27
- activate: (_app) => {
28
- console.log('JupyterLab extension jupyterlab-quarto is activated!');
29
- // Create a markdown rendering manager
30
- return markdownItManager();
28
+ requires: [IEditorThemeRegistry, IEditorLanguageRegistry],
29
+ activate: (_app, themeRegistry, languageRegistry) => {
30
+ console.log('JupyterLab extension @quarto/jupyterlab-quarto is activated!');
31
+ // Create a markdown rendering manager
32
+ return markdownItManager(themeRegistry, languageRegistry);
31
33
  }
32
34
  };
33
35
  // Markdown It Extensions which provide base Pandoc behavior
@@ -57,4 +59,3 @@ const kQuartoExtensions = [
57
59
  ];
58
60
  // The extensions that should be enabled for Jupyter
59
61
  export default [plugin, ...kPandocExtensions, ...kQuartoExtensions];
60
- //# sourceMappingURL=index.js.map
package/lib/manager.d.ts CHANGED
@@ -1,8 +1,8 @@
1
+ import { IEditorLanguageRegistry, IEditorThemeRegistry } from '@jupyterlab/codemirror';
1
2
  import { Options } from 'markdown-it';
2
3
  import { RenderedMarkdown } from './widgets';
3
4
  import { MarkdownItPluginProvider, Renderer } from './types';
4
- export declare function markdownItManager(): {
5
+ export declare function markdownItManager(themeRegistry: IEditorThemeRegistry, languageRegistry: IEditorLanguageRegistry): {
5
6
  registerPlugin(provider: MarkdownItPluginProvider): void;
6
7
  getRenderer(widget: RenderedMarkdown, options?: Options): Promise<Renderer>;
7
8
  };
8
- //# sourceMappingURL=manager.d.ts.map
package/lib/manager.js CHANGED
@@ -1,24 +1,23 @@
1
1
  /*
2
- * manager.ts
3
- *
4
- * Copyright (C) 2020-2023 Posit Software, PBC
5
- *
6
- */
2
+ * manager.ts
3
+ *
4
+ * Copyright (C) 2020-2023 Posit Software, PBC
5
+ *
6
+ */
7
7
  import { markdownRendererFactory } from '@jupyterlab/rendermime';
8
- import { CodeMirrorEditor } from '@jupyterlab/codemirror';
9
8
  import MarkdownIt from 'markdown-it';
10
9
  import { RenderedMarkdown } from './widgets';
11
- import { codeMirrorHighlight, codeMirrorPreloadHook } from './hooks/codemirror';
10
+ import { codeMirrorHighlighter, codeMirrorPreloadHook } from './hooks/codemirror';
12
11
  // Provides resolved MarkdownIt options using the passed in options, the plugin
13
12
  // options, and default options.
14
- const resolveOptions = (widget, options, providers) => {
13
+ const resolveOptions = (widget, options, providers, themeRegistry, languageRegistry) => {
15
14
  // Build options table
16
15
  let allOptions = {
17
16
  html: true,
18
17
  linkify: true,
19
18
  typographer: true,
20
- langPrefix: `cm-s-${CodeMirrorEditor.defaultConfig.theme} language-`,
21
- highlight: codeMirrorHighlight
19
+ langPrefix: `cm-s-${themeRegistry.defaultTheme} language-`,
20
+ highlight: codeMirrorHighlighter(languageRegistry)
22
21
  };
23
22
  for (const plugin of providers) {
24
23
  if (plugin.options) {
@@ -36,7 +35,7 @@ const resolveOptions = (widget, options, providers) => {
36
35
  ...options
37
36
  };
38
37
  };
39
- export function markdownItManager() {
38
+ export function markdownItManager(themeRegistry, languageRegistry) {
40
39
  // The plugin providers
41
40
  const pluginProviders = new Map();
42
41
  // The IMarkdownItManager
@@ -50,14 +49,14 @@ export function markdownItManager() {
50
49
  const providers = [...pluginProviders.values()];
51
50
  providers.sort(sortRanked);
52
51
  // Create MarkdownIt instance
53
- const allOptions = resolveOptions(widget, options, providers);
52
+ const allOptions = resolveOptions(widget, options, providers, themeRegistry, languageRegistry);
54
53
  let md = new MarkdownIt('default', allOptions);
55
54
  // Lifecycle hooks
56
55
  const preParseHooks = [];
57
56
  const postRenderHooks = [];
58
57
  // add mode pre-loading hook if using default highlighter
59
- if (codeMirrorHighlight === allOptions.highlight) {
60
- preParseHooks.push(codeMirrorPreloadHook());
58
+ if (codeMirrorHighlighter(languageRegistry) === allOptions.highlight) {
59
+ preParseHooks.push(codeMirrorPreloadHook(languageRegistry));
61
60
  }
62
61
  // Build MarkdownIt and load lifecycle hooks
63
62
  for (const provider of providers) {
@@ -83,7 +82,7 @@ export function markdownItManager() {
83
82
  postRenderHooks.sort(sortRanked);
84
83
  return {
85
84
  // Parse and render Markdown
86
- render: (content) => {
85
+ render: content => {
87
86
  return md.render(content);
88
87
  },
89
88
  // Run hooks serially
@@ -114,4 +113,3 @@ const sortRanked = (left, right) => {
114
113
  var _a, _b;
115
114
  return ((_a = left.rank) !== null && _a !== void 0 ? _a : kDefaultRank) - ((_b = right.rank) !== null && _b !== void 0 ? _b : kDefaultRank);
116
115
  };
117
- //# sourceMappingURL=manager.js.map
@@ -1,3 +1,2 @@
1
- import type MarkdownIt from "markdown-it/lib";
1
+ import type MarkdownIt from 'markdown-it/lib';
2
2
  export declare const calloutPlugin: (md: MarkdownIt) => void;
3
- //# sourceMappingURL=callouts.d.ts.map
@@ -1,19 +1,19 @@
1
- import Token from "markdown-it/lib/token";
2
- import { addClass, readAttrValue } from "./utils/markdownit";
3
- import { kTokDivClose, kTokDivOpen } from "./divs";
4
- const kTokCalloutOpen = "quarto_callout_open";
5
- const kTokCalloutClose = "quarto_callout_close";
6
- const kTokCalloutTitleOpen = "quarto_callout_title_open";
7
- const kTokCalloutTitleClose = "quarto_callout_title_close";
8
- const kTokCalloutContentOpen = "quarto_callout_content_open";
9
- const kTokCalloutContentClose = "quarto_callout_content_close";
10
- const kCalloutPrefix = "callout-";
11
- const kCalloutRuleName = "quarto-callouts";
1
+ import Token from 'markdown-it/lib/token';
2
+ import { addClass, readAttrValue } from './utils/markdownit';
3
+ import { kTokDivClose, kTokDivOpen } from './divs';
4
+ const kTokCalloutOpen = 'quarto_callout_open';
5
+ const kTokCalloutClose = 'quarto_callout_close';
6
+ const kTokCalloutTitleOpen = 'quarto_callout_title_open';
7
+ const kTokCalloutTitleClose = 'quarto_callout_title_close';
8
+ const kTokCalloutContentOpen = 'quarto_callout_content_open';
9
+ const kTokCalloutContentClose = 'quarto_callout_content_close';
10
+ const kCalloutPrefix = 'callout-';
11
+ const kCalloutRuleName = 'quarto-callouts';
12
12
  export const calloutPlugin = (md) => {
13
13
  // Handle pandoc-style divs
14
- md.core.ruler.push(kCalloutRuleName, (state) => {
14
+ md.core.ruler.push(kCalloutRuleName, state => {
15
15
  const noteStartCallout = (callout, depth) => {
16
- if (calloutDepth == -1) {
16
+ if (calloutDepth === -1) {
17
17
  calloutDepth = depth;
18
18
  }
19
19
  state.env['quarto-active-callout'] = callout;
@@ -29,28 +29,28 @@ export const calloutPlugin = (md) => {
29
29
  return calloutDepth === depth;
30
30
  };
31
31
  const titleOpenTok = (title) => {
32
- const token = new Token(kTokCalloutTitleOpen, "", 1);
33
- token.tag = "div";
34
- token.attrs = [["class", "callout-header"]];
32
+ const token = new Token(kTokCalloutTitleOpen, '', 1);
33
+ token.tag = 'div';
34
+ token.attrs = [['class', 'callout-header']];
35
35
  if (title) {
36
- token.attrs.push(["title", title]);
36
+ token.attrs.push(['title', title]);
37
37
  }
38
38
  return token;
39
39
  };
40
40
  const titleCloseTok = () => {
41
- const token = new Token(kTokCalloutTitleClose, "", -1);
42
- token.tag = "div";
41
+ const token = new Token(kTokCalloutTitleClose, '', -1);
42
+ token.tag = 'div';
43
43
  return token;
44
44
  };
45
45
  const contentOpenTok = () => {
46
- const token = new Token(kTokCalloutContentOpen, "", 1);
47
- token.tag = "div";
48
- token.attrs = [["class", "callout-body-container callout-body"]];
46
+ const token = new Token(kTokCalloutContentOpen, '', 1);
47
+ token.tag = 'div';
48
+ token.attrs = [['class', 'callout-body-container callout-body']];
49
49
  return token;
50
50
  };
51
51
  const contentCloseTok = () => {
52
- const token = new Token(kTokCalloutContentClose, "", -1);
53
- token.tag = "div";
52
+ const token = new Token(kTokCalloutContentClose, '', -1);
53
+ token.tag = 'div';
54
54
  return token;
55
55
  };
56
56
  const outTokens = [];
@@ -58,44 +58,44 @@ export const calloutPlugin = (md) => {
58
58
  let divDepth = 0;
59
59
  // just started callout - process title
60
60
  // finished processing title - process content
61
- let calloutState = "scanning";
61
+ let calloutState = 'scanning';
62
62
  for (const token of state.tokens) {
63
63
  switch (calloutState) {
64
- case "add-title":
65
- if (token.type === "heading_open") {
64
+ case 'add-title':
65
+ if (token.type === 'heading_open') {
66
66
  outTokens.push(titleOpenTok());
67
- calloutState = "capturing-title";
67
+ calloutState = 'capturing-title';
68
68
  }
69
69
  else {
70
70
  const callout = activeCallout();
71
71
  outTokens.push(titleOpenTok(callout.title));
72
72
  outTokens.push(titleCloseTok());
73
- calloutState = "add-body";
73
+ calloutState = 'add-body';
74
74
  }
75
75
  break;
76
- case "capturing-title":
77
- if (token.type === "heading_close") {
76
+ case 'capturing-title':
77
+ if (token.type === 'heading_close') {
78
78
  outTokens.push(titleCloseTok());
79
- calloutState = "add-body";
79
+ calloutState = 'add-body';
80
80
  }
81
81
  else {
82
82
  outTokens.push(token);
83
83
  }
84
84
  break;
85
- case "add-body":
85
+ case 'add-body':
86
86
  outTokens.push(contentOpenTok());
87
87
  outTokens.push(token);
88
- calloutState = "capturing-body";
88
+ calloutState = 'capturing-body';
89
89
  break;
90
- case "scanning":
90
+ case 'scanning':
91
91
  default:
92
92
  if (token.type === kTokDivOpen) {
93
93
  divDepth++;
94
94
  const callout = parseCallout(token.attrs);
95
95
  if (callout) {
96
96
  noteStartCallout(callout, divDepth);
97
- calloutState = "add-title";
98
- const openCallout = new Token(kTokCalloutOpen, "", 1);
97
+ calloutState = 'add-title';
98
+ const openCallout = new Token(kTokCalloutOpen, '', 1);
99
99
  openCallout.attrs = openCallout.attrs || [];
100
100
  openCallout.meta = callout;
101
101
  outTokens.push(openCallout);
@@ -107,7 +107,7 @@ export const calloutPlugin = (md) => {
107
107
  else if (token.type === kTokDivClose) {
108
108
  if (isCloseCallout(divDepth)) {
109
109
  outTokens.push(contentCloseTok());
110
- outTokens.push(new Token(kTokCalloutClose, "", -1));
110
+ outTokens.push(new Token(kTokCalloutClose, '', -1));
111
111
  noteCloseCallout();
112
112
  }
113
113
  else {
@@ -141,11 +141,11 @@ function renderStartCallout(tokens, idx, _options, _env, self) {
141
141
  }
142
142
  // Render pandoc-style divs
143
143
  function renderEndCallout() {
144
- return `</div>`;
144
+ return '</div>';
145
145
  }
146
146
  function renderStartCalloutTitle(tokens, idx) {
147
147
  const token = tokens[idx];
148
- const title = readAttrValue("title", token.attrs) || "";
148
+ const title = readAttrValue('title', token.attrs) || '';
149
149
  const startContent = `
150
150
  <div class="callout-header">
151
151
  <div class="callout-icon-container">
@@ -156,43 +156,45 @@ function renderStartCalloutTitle(tokens, idx) {
156
156
  return startContent;
157
157
  }
158
158
  function renderEndCalloutTitle() {
159
- return `</div>\n</div>`;
159
+ return '</div>\n</div>';
160
160
  }
161
161
  const calloutAppearance = (val) => {
162
162
  if (val) {
163
163
  switch (val) {
164
- case "minimal":
165
- return "minimal";
166
- case "simple":
167
- return "simple";
168
- case "default":
164
+ case 'minimal':
165
+ return 'minimal';
166
+ case 'simple':
167
+ return 'simple';
168
+ case 'default':
169
169
  default:
170
- return "default";
170
+ return 'default';
171
171
  }
172
172
  }
173
173
  else {
174
- return "default";
174
+ return 'default';
175
175
  }
176
176
  };
177
177
  const parseCallout = (attrs) => {
178
178
  if (attrs === null) {
179
179
  return undefined;
180
180
  }
181
- const classAttr = attrs.find((attr) => { return attr[0] === "class"; });
181
+ const classAttr = attrs.find(attr => {
182
+ return attr[0] === 'class';
183
+ });
182
184
  if (!classAttr) {
183
185
  return undefined;
184
186
  }
185
- const classes = classAttr[1].split(" ");
186
- const calloutClass = classes.find((clz) => {
187
+ const classes = classAttr[1].split(' ');
188
+ const calloutClass = classes.find(clz => {
187
189
  return clz.startsWith('callout-');
188
190
  });
189
191
  if (calloutClass) {
190
- const type = calloutClass.replace(kCalloutPrefix, "");
191
- const title = readAttrValue("title", attrs) || type.slice(0, 1).toUpperCase() + type.slice(1);
192
- ;
193
- const appearance = calloutAppearance(readAttrValue("appearance", attrs));
192
+ const type = calloutClass.replace(kCalloutPrefix, '');
193
+ const title = readAttrValue('title', attrs) ||
194
+ type.slice(0, 1).toUpperCase() + type.slice(1);
195
+ const appearance = calloutAppearance(readAttrValue('appearance', attrs));
194
196
  return {
195
- type: type || "note",
197
+ type: type || 'note',
196
198
  clz: calloutClass,
197
199
  title,
198
200
  appearance
@@ -203,7 +205,6 @@ const parseCallout = (attrs) => {
203
205
  }
204
206
  };
205
207
  const appearanceClass = (appearance) => {
206
- const style = appearance || "default";
208
+ const style = appearance || 'default';
207
209
  return `callout-style-${style}`;
208
210
  };
209
- //# sourceMappingURL=callouts.js.map