Path: blob/main/extensions/ipynb/notebook-src/cellAttachmentRenderer.ts
3292 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import type * as MarkdownIt from 'markdown-it';6import type * as MarkdownItToken from 'markdown-it/lib/token';7import type { RendererContext } from 'vscode-notebook-renderer';89interface MarkdownItRenderer {10extendMarkdownIt(fn: (md: MarkdownIt) => void): void;11}1213export async function activate(ctx: RendererContext<void>) {14const markdownItRenderer = (await ctx.getRenderer('vscode.markdown-it-renderer')) as MarkdownItRenderer | any;15if (!markdownItRenderer) {16throw new Error(`Could not load 'vscode.markdown-it-renderer'`);17}1819markdownItRenderer.extendMarkdownIt((md: MarkdownIt) => {20const original = md.renderer.rules.image;21md.renderer.rules.image = (tokens: MarkdownItToken[], idx: number, options, env, self) => {22const token = tokens[idx];23const src = token.attrGet('src');24const attachments: Record<string, Record<string, string>> | undefined = env.outputItem.metadata?.attachments;25if (attachments && src && src.startsWith('attachment:')) {26const imageAttachment = attachments[tryDecodeURIComponent(src.replace('attachment:', ''))];27if (imageAttachment) {28// objEntries will always be length 1, with objEntries[0] holding [0]=mime,[1]=b6429// if length = 0, something is wrong with the attachment, mime/b64 weren't copied over30const objEntries = Object.entries(imageAttachment);31if (objEntries.length) {32const [attachmentKey, attachmentVal] = objEntries[0];33const b64Markdown = 'data:' + attachmentKey + ';base64,' + attachmentVal;34token.attrSet('src', b64Markdown);35}36}37}3839if (original) {40return original(tokens, idx, options, env, self);41} else {42return self.renderToken(tokens, idx, options);43}44};45});46}4748function tryDecodeURIComponent(uri: string) {49try {50return decodeURIComponent(uri);51} catch {52return uri;53}54}555657