index.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import {
  4. ILayoutRestorer,
  5. JupyterLab,
  6. JupyterLabPlugin
  7. } from '@jupyterlab/application';
  8. import { InstanceTracker } from '@jupyterlab/apputils';
  9. import { ISettingRegistry } from '@jupyterlab/coreutils';
  10. import {
  11. IRenderMimeRegistry,
  12. markdownRendererFactory
  13. } from '@jupyterlab/rendermime';
  14. import {
  15. MarkdownViewer,
  16. MarkdownViewerFactory,
  17. MarkdownDocument,
  18. IMarkdownViewerTracker
  19. } from '@jupyterlab/markdownviewer';
  20. /**
  21. * The command IDs used by the markdownviewer plugin.
  22. */
  23. namespace CommandIDs {
  24. export const markdownPreview = 'markdownviewer:open';
  25. }
  26. /**
  27. * The name of the factory that creates markdown viewer widgets.
  28. */
  29. const FACTORY = 'Markdown Preview';
  30. /**
  31. * The markdown viewer plugin.
  32. */
  33. const plugin: JupyterLabPlugin<IMarkdownViewerTracker> = {
  34. activate,
  35. id: '@jupyterlab/markdownviewer-extension:plugin',
  36. provides: IMarkdownViewerTracker,
  37. requires: [ILayoutRestorer, IRenderMimeRegistry, ISettingRegistry],
  38. autoStart: true
  39. };
  40. /**
  41. * Activate the markdown viewer plugin.
  42. */
  43. function activate(
  44. app: JupyterLab,
  45. restorer: ILayoutRestorer,
  46. rendermime: IRenderMimeRegistry,
  47. settingRegistry: ISettingRegistry
  48. ): IMarkdownViewerTracker {
  49. const { commands, docRegistry } = app;
  50. // Add the markdown renderer factory.
  51. rendermime.addFactory(markdownRendererFactory);
  52. const namespace = 'markdownviewer-widget';
  53. const tracker = new InstanceTracker<MarkdownDocument>({
  54. namespace
  55. });
  56. let config: Partial<MarkdownViewer.IConfig> = {
  57. ...MarkdownViewer.defaultConfig
  58. };
  59. /**
  60. * Update the settings of a widget.
  61. */
  62. function updateWidget(widget: MarkdownViewer): void {
  63. Object.keys(config).forEach((k: keyof MarkdownViewer.IConfig) => {
  64. widget.setOption(k, config[k]);
  65. });
  66. }
  67. /**
  68. * Update the setting values.
  69. */
  70. function updateSettings(settings: ISettingRegistry.ISettings) {
  71. config = settings.composite as Partial<MarkdownViewer.IConfig>;
  72. tracker.forEach(widget => {
  73. updateWidget(widget.content);
  74. });
  75. }
  76. // Fetch the initial state of the settings.
  77. settingRegistry
  78. .load(plugin.id)
  79. .then((settings: ISettingRegistry.ISettings) => {
  80. settings.changed.connect(() => {
  81. updateSettings(settings);
  82. });
  83. updateSettings(settings);
  84. })
  85. .catch((reason: Error) => {
  86. console.error(reason.message);
  87. });
  88. // Register the MarkdownViewer factory.
  89. const factory = new MarkdownViewerFactory({
  90. rendermime,
  91. name: FACTORY,
  92. primaryFileType: docRegistry.getFileType('markdown'),
  93. fileTypes: ['markdown'],
  94. defaultRendered: ['markdown']
  95. });
  96. factory.widgetCreated.connect((sender, widget) => {
  97. // Notify the instance tracker if restore data needs to update.
  98. widget.context.pathChanged.connect(() => {
  99. tracker.save(widget);
  100. });
  101. // Handle the settings of new widgets.
  102. updateWidget(widget.content);
  103. tracker.add(widget);
  104. });
  105. docRegistry.addWidgetFactory(factory);
  106. // Handle state restoration.
  107. restorer.restore(tracker, {
  108. command: 'docmanager:open',
  109. args: widget => ({ path: widget.context.path, factory: FACTORY }),
  110. name: widget => widget.context.path
  111. });
  112. commands.addCommand(CommandIDs.markdownPreview, {
  113. label: 'Markdown Preview',
  114. execute: args => {
  115. let path = args['path'];
  116. if (typeof path !== 'string') {
  117. return;
  118. }
  119. return commands.execute('docmanager:open', {
  120. path,
  121. factory: FACTORY,
  122. options: args['options']
  123. });
  124. }
  125. });
  126. return tracker;
  127. }
  128. /**
  129. * Export the plugin as default.
  130. */
  131. export default plugin;