Notebooks and Renderers
Purpose and Scope
VS Code notebooks combine editable cells, rendered output, language services, and webview-based rendering into a single document experience. The public documentation describes Jupyter notebooks as canvases that mix Markdown text with executable Python code, and it also describes AI-assisted workflows for scaffolding and editing notebook cells. In this repository slice, the strongest implementation evidence is around Markdown cells: how Markdown language features attach to notebook documents, how Markdown notebook cells are rendered safely, and how the same Markdown preview infrastructure supports rich rendered documents outside notebooks.
Sources: extensions/markdown-language-features/src/client/client.ts, extensions/markdown-language-features/notebook/index.ts, extensions/markdown-language-features/preview-src/index.ts
A useful way to read this subsystem is to separate notebook document support from renderer behavior. Notebook document support lets language features understand that a Markdown cell is part of a notebook, not only a standalone .md file. Renderer behavior is the webview-side work that turns Markdown source into displayed HTML, applies VS Code styling rules, handles links and images, and keeps the rendered view aligned with the editor. Those responsibilities are related, but they are intentionally implemented in different modules so that editing, previewing, and notebook-cell rendering can evolve independently.
Relevant Source Files
extensions/markdown-language-features/src/client/client.ts- starts the Markdown language client, configures Markdown document selectors, file watching, diagnostics, and notebook synchronization for Markdown cells.extensions/markdown-language-features/notebook/index.ts- implements the Markdown notebook renderer activation function, MarkdownIt rendering, DOMPurify sanitization, link rendering, header rendering, and notebook-specific styles.extensions/markdown-language-features/preview-src/index.ts- implements the Markdown preview webview client, including initial HTML loading, persisted state, scroll synchronization, image handling, diff scroll integration, and message posting back to VS Code.extensions/markdown-language-features/src/commands/index.ts- registers Markdown commands such as preview, preview-to-side, refresh, render document, source/preview toggles, image commands, and preview security selection.src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts- provides core editor inplace replacement behavior for numbers and common value sets, which applies to editor text interactions including cell editors that use the shared editor model.extensions/copilot/src/extension/completions-core/vscode-node/extension/src/panelShared/languages/markdown-latex-combined.tmLanguage.ts- contributes a Copilot-side grammar path for Markdown and LaTeX combined content, relevant to AI-generated or displayed notebook-style prose and math contexts.
Core Notebook Primitives
The first primitive is the notebook document itself: a file such as .ipynb is opened as an ordered set of cells, commonly mixing Markdown and code. Official VS Code documentation explains that the Jupyter experience includes creating, opening, saving, running cells, inspecting variables, connecting to remote Jupyter servers, and debugging notebooks. This page focuses on the repository modules that make Markdown cells and rendered Markdown behave consistently inside that larger notebook surface, rather than on kernel execution or Python environment management.
The second primitive is the Markdown cell. In startClient, the Markdown language client configures a normal Markdown document selector and then registers notebook document synchronization when the LSP notebook feature is available. The registration selects any notebook type, but narrows cells to language: 'markdown'. That means Markdown language features can participate in notebooks without requiring each notebook provider to reimplement Markdown link resolution, diagnostics, or file-reference behavior for Markdown cells.
Sources: extensions/markdown-language-features/src/client/client.ts
The third primitive is the renderer. extensions/markdown-language-features/notebook/index.ts exports an activate function typed as a vscode-notebook-renderer activation function. It creates a MarkdownIt instance with HTML enabled, linkification enabled, and a highlighter that wraps fenced code blocks in a VS Code-specific vscode-code-block container. The renderer also disables fuzzy links, adds named header and link rendering, injects CSS for notebook cell layout, and sanitizes generated markup through DOMPurify with an explicit allow-list of HTML and SVG tags.
Sources: extensions/markdown-language-features/notebook/index.ts
System-to-Code Mapping
Markdown notebook rendering and Markdown preview share a conceptual pipeline: parse source, produce HTML, apply VS Code-aware presentation rules, and communicate with the surrounding workbench. The notebook renderer is optimized for cell output inside the notebook editor, while the preview webview handles a full-document view with scroll state, fragment navigation, image loading, line changes, and diff scroll synchronization. This split lets the notebook UI keep each cell lightweight while the preview UI supports richer document-level navigation features such as source-line reveal and persisted scroll progress.
Sources: extensions/markdown-language-features/notebook/index.ts, extensions/markdown-language-features/preview-src/index.ts
The command registration layer exposes the Markdown-facing actions that users recognize from the Command Palette and editor menus. registerMarkdownCommands wires command objects into a CommandManager: preview commands, source/preview reopening, refresh, render document, plugin reload, image commands, link and image insertion from the workspace, preview locking, and preview security selection. These are not notebook-kernel commands; they are Markdown document and preview commands. They still matter for notebook users because Markdown cells depend on the same rendering expectations and Markdown feature vocabulary.
Sources: extensions/markdown-language-features/src/commands/index.ts
Rendering and Security Flow
Rendering starts by turning Markdown source into HTML, but VS Code cannot simply inject arbitrary rendered content. Notebook Markdown rendering uses DOMPurify and a constrained tag list, including common text tags, tables, images, media tags, and selected SVG tags. The renderer also adjusts CSS for notebook-specific affordances: empty Markdown cells show placeholder content, images are constrained to the available cell area, links avoid underlines until hover, focus outlines remain visible, tables collapse borders, and headings are normalized for notebook display. These details preserve readability while reducing the risk of unsafe or visually disruptive markup.
Sources: extensions/markdown-language-features/notebook/index.ts
The Markdown preview webview has a broader lifecycle because it represents an entire rendered document. On document load, it parses initial Markdown HTML from data attributes, appends the resulting elements to the body, evaluates embedded script-bearing elements through its own DOM handling path, restores scroll state, applies line-change markers, and waits for images before synchronizing scroll. It also constructs a poster around the VS Code webview API so CSP alerts and style-loading monitors can report information back to the extension host.
Sources: extensions/markdown-language-features/preview-src/index.ts
API Components and Source-Level Contracts
The Markdown language client exposes request-style methods that are useful to notebook Markdown cells and standalone Markdown files alike. resolveLinkTarget resolves Markdown link destinations; getEditForFileRenames asks the language server for edits after file moves; getReferencesToFileInWorkspace searches for Markdown references to a resource; prepareUpdatePastedLinks and getUpdatePastedLinksEdit support link updates during paste flows. The client options also enable configuration synchronization for the markdown section, filesystem watching over Markdown extensions, pull diagnostics on changes and tabs, and HTML support for Markdown.
Sources: extensions/markdown-language-features/src/client/client.ts
Compact reference for the source-backed components:
| Component | Public contract visible in source | Notebook relevance |
|---|---|---|
startClient(factory, parser) | Creates the Markdown language client and registers Markdown notebook-cell sync when supported. | Enables Markdown language features in notebook cells. |
MdLanguageClient | Sends Markdown protocol requests for links, renames, references, and pasted-link edits. | Keeps Markdown cells aligned with workspace-aware Markdown behavior. |
activate(ctx) in the notebook renderer | Initializes MarkdownIt, renderer helpers, sanitizer configuration, and notebook CSS. | Renders Markdown cells safely and consistently. |
registerMarkdownCommands(...) | Registers preview, render, security, image, link, and source/preview commands. | Defines the command vocabulary around Markdown rendering. |
BasicInplaceReplace.INSTANCE | Navigates numeric values and predefined text value sets. | Supplies shared editor behavior inside text editors, including cell editors. |
Editing, AI, and Cell-Level Interaction
Official notebook docs describe inline chat in notebook cells and the ability to reference kernel variables in prompts. The repository evidence here connects that user-facing story to two lower-level mechanisms. Markdown cells receive language-service participation through notebook synchronization, and cell editors inherit common editor supports such as inplace replacement. BasicInplaceReplace increments or decrements numeric text while preserving decimal precision and cycles values such as true/false, public/protected/private, and related casing variants. These small editing behaviors matter because notebook cells are still text editors with the normal VS Code editing model underneath.
Sources: extensions/markdown-language-features/src/client/client.ts, src/vs/editor/common/languages/supports/inplaceReplaceSupport.ts
AI-assisted notebook work often produces prose, Markdown, code blocks, mathematical notation, and explanatory output. The requested source set includes a Copilot path for a combined Markdown and LaTeX grammar, which is consistent with notebook-style content where Markdown explanations and mathematical expressions commonly appear together. Treat this as a rendering and language-context adjacency: the notebook renderer source shows how Markdown cells become sanitized HTML, while the Copilot grammar path shows that AI-facing UI code has a named surface for Markdown-plus-LaTeX content classification.
Sources: extensions/copilot/src/extension/completions-core/vscode-node/extension/src/panelShared/languages/markdown-latex-combined.tmLanguage.ts, extensions/markdown-language-features/notebook/index.ts
Testing Signals and Next Steps
For validation, start with the behavior boundaries visible in these files. A renderer change should be checked against sanitizer allow-lists, link rendering, empty-cell styling, image sizing, table styling, and code-block wrapping. A language-client change should preserve Markdown document selectors, notebook-cell registration, diagnostics matching, and request payload shapes. A preview change should be checked for persisted state, image-load ordering, line-change application, diff scrolling, and message posting. These are practical review points even when the end-to-end notebook smoke tests live elsewhere in the larger repository.
Next, read this page together with markdown-emmet-mermaid for Markdown preview feature depth, copilot-and-ai-overview for AI editing surfaces, and remote-web-and-server for browser-hosted notebook workflows. If you are changing notebook Markdown rendering, begin in extensions/markdown-language-features/notebook/index.ts; if you are changing Markdown language behavior inside notebook cells, begin in extensions/markdown-language-features/src/client/client.ts; and if the change affects full Markdown previews, compare the behavior against extensions/markdown-language-features/preview-src/index.ts before shipping.