Change:
Tracks adding an official API for extending markdown rendering in notebooks. Internally we've already implemented and shipped basic support for this, but this api is not suitable for public consumption This is a follow up on / There are a range of different markdown flavors used across the various notebook ecosystems. Some notebooks for example, while others use specific markdown parsers with their own set of extensions/quirks VS Code can not include all of the potential markdown features that a given notebook may want, so we instead plan to allow markdown rendering to be extended (and potentially replaced) by extensions. There are two main use cases we are interested in: Augmentation: An extension wants to augment an existing markdown parsers with a simple new feature, such as syntax supportReplacement: An notebook requires a fully custom renderer for markdown With , we the ability to fully replace VS Code's built-in markdown rendering with a renderer provided by an extension. The new markdown rendering also happens entirely in the back layer webview of notebook (similar to output renderers). At the moment, only built-in extensions can replace VS Code's markdown renderer We are using this api to render notebook markdown with provided by a built-in extension. We also an adhoc api that lets the markdown-it renderer load markdown-it plugins. We are using this to load and support Neither of these apis are ready for external consumption Should we make this generic? For example, instead of restricting this to markdown, are there notebooks out there that use or for their inputs? Should we have an "input renderer" API that matches how our "output renderer" api works How do these features fit with kernels and the rest of notebook apis? Should a kernel be able to specify which flavor of markdown it requires? Does it make sense to let a separate extension add support for new markdown syntax like , or should this always come from the notebook provider itself? Does fully replacing our markdown rendering even make sense for anyone besides markdown it? When a notebook ecosystem does use a specific markdown flavor, it is usually powered some non-js tool. This means we cannot load it in the webview, so at a minimum we'd have to provide some way to let the renderer call back to extension code so that it can run a native script. This sounds like a recipe for lots of delays with the rendering I guess the main question is if markdown-it is flexible enough so that it could handle most of the (common) notebook use cases. If it is, we will not need to support fully replacing the markdown renderer
Here's an approach I've prototyped for the api. This tries to support both replacement and augmentation of renderers, although we may ultimately decide that we only want to support extending a version of that we ship (similar to what our built-in markdown extension supports) For a renderer replacement: For a renderer that augments another one: First for an augmentation, in this case : Now for the renderer itself, which fully replaces VS Code's markdown renderer: The above may be overly complicated. Specifically if we only need to support augmenting markdown-it, we don't have to standardize all the weird globals stuff going on in the entrypoint above Still, it might be nice to define a proper api for replacing markdown renderers, even if we just use it internally. is pretty ugly It would be really nice if we could defer loading resources until we really need them (or at least not block notebook open because we are loading resources that are never used) For example, if a notebook supports math but none of its cells use math, we should not load . We can quickly check if any of the cells may contain math equations just by seeing if they contain at least two dollar sign characters somewhere in the text
This is an interesting thought. We have discussed if we should blur the line between code and markdown cells, e.g there is just cells with output and cells using the markdown language get a different cell editor
Implements the proposed API. Performance seems about the same I also renamed the extension point from to to prototype what a more generic api would look like
This will be very similar to "normal" output renderers. I like that direction and wonder if they can be the same at one point?
Just a quick note that we would find this API very useful, thanks for working on it :-) We work with which builds the tool . We're also maintaining a flavor of markdown called , which has extensible syntax and features more suited for scientific communication. We have a , and plan to incorporate more MyST Markdown into Jupyter Notebooks. This API would let us do so in VSCode relatively easily via the markdown renderer above, which would be super cool
Before finalizing this, we should also consider preloads for renderers: I think these can probably slot into the contribution
As requested Please could we provide an API whereby the renderer can access Notebook Cell metadata when rendering Notebook markdown cells. Usage in Jupyter extension: In jupyter users attach images to the markdown cells (the images are base64 encoded and saved in the cell metadata), when rendering the markdown, the image is decoded and displayed as though the image was available locally. Similarly adding support for the Python variables in Markdown cells feature requires this functionality (https://jupyter-contrib-) we need to be able to access the cell metadata (as the variables are stored as metadata in the cells)
Lets a renderer that extends our built-in markdown rendering access the current cell metadata (you would do this while rendering by using markdown-it's property) Let me know if this is enough for your use cases. I'm actually not sure if images are stored in the cell's metadata or in the notebook's metadata (if it's the latter, we would also need to implement )
Will try this out and let you know, thanks

Discussion:
{ type: 'string', }, <del> // todo@connor4312 + @mjbvz: uncomment this once it's ready for external adoption // { // 	type: 'object', // 	required: ['extends', 'path'], // 	properties: { // 		extends: { // 			type: 'string', // 			description: nls.localize('contributes.notebook.renderer.entrypoint.extends', 'Existing renderer that this one extends.'), // 		}, // 		path: { // 			type: 'string', // 			description: nls.localize('contributes.notebook.renderer.entrypoint', 'File to load in the webview to render the extension.'), // 		}, // 	} // } </del> <ins> { type: 'object', required: ['extends', 'path'], properties: { extends: { type: 'string', description: nls.localize('contributes.notebook.renderer.entrypoint.extends', 'Existing renderer that this one extends.'), }, path: { type: 'string', description: nls.localize('contributes.notebook.renderer.entrypoint', 'File to load in the webview to render the extension.'), }, } } </ins> ] }, [NotebookRendererContribution.hardDependencies]: {

export const RENDERER_NOT_AVAILABLE = '_notAvailable'; <del> export type NotebookRendererEntrypoint = string | { extends: string; path: string }; </del> <ins> export type NotebookRendererEntrypoint = string | { readonly extends: string; readonly path: string }; </ins> export enum NotebookRunState { Running = 1,