<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as DOM from 'vs/base/browser/dom';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { RGBA, Color } from 'vs/base/common/color';
import { ansiColorIdentifiers } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import { isArray } from 'vs/base/common/types';
import { NotebookHandler } from 'vs/workbench/contrib/notebook/browser/cellRenderer';
import { IOutput } from 'vs/editor/common/modes';

export function registerMineTypeRenderer(types: string[], renderer: IMimeRenderer) {
	types.forEach(type => {
		MimeTypeRenderer.instance.register(type, renderer);
	});
}

export interface IRenderOutput {
	element: HTMLElement;
	whitespaceElement?: HTMLElement;
	shadowContent?: string;
	hasDynamicHeight: boolean;
}

interface IMimeRenderer {
	render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput;
}

export class MimeTypeRenderer {
	static instance = new MimeTypeRenderer();
	private readonly _renderers = new Map<string, IMimeRenderer>();

	register(type: string, renderer: IMimeRenderer) {
		this._renderers.set(type, renderer);
	}

	getRenderer(type: string) {
		return this._renderers.get(type);
	}

	static render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput | null {
		return MimeTypeRenderer.instance.getRenderer(output.output_type)?.render(output, themeService, webviewService, notebookHandler) ?? null;
	}
}

registerMineTypeRenderer(['stream'], {
	render: (
		output: IOutput,
		themeService: IThemeService,
		webviewService: IWebviewService
	) => {
		const outputNode = document.createElement('div');
		const contentNode = document.createElement('p');
		contentNode.innerText = output.text;
		outputNode.appendChild(contentNode);
		return {
			element: outputNode,
			hasDynamicHeight: false
		};
	}
});

registerMineTypeRenderer(['error'], {
	render: (
		output: IOutput,
		themeService: IThemeService,
		webviewService: IWebviewService
	) => {
		const outputNode = document.createElement('div');
		const traceback = document.createElement('pre');
		DOM.addClasses(traceback, 'traceback');
		if (output.traceback) {
			for (let j = 0; j < output.traceback.length; j++) {
				traceback.appendChild(handleANSIOutput(output.traceback[j], themeService));
			}
		}
		outputNode.appendChild(traceback);
		return {
			element: outputNode,
			hasDynamicHeight: false
		};
	}
});

// Display Order
//
// application/json
// application/javascript
// text/html
// image/svg+xml
// text/markdown
// text/latex
// image/svg+xml
// image/gif
// image/png
// image/jpeg
// application/pdf
// text/plain

class RichDisplayRenderer implements IMimeRenderer {
	render(output: any, themeService: IThemeService, webviewService: IWebviewService, notebookHandler: NotebookHandler): IRenderOutput {
		const display = document.createElement('div');
		const outputNode = document.createElement('div');
		let hasDynamicHeight = false;
		DOM.addClasses(display, 'display');

		if (output.data) {
			if (output.data['text/html']) {
				let data = output.data['text/html'];
				let str = isArray(data) ? data.join('') : data;
				hasDynamicHeight = false;
				return {
					element: outputNode,
					shadowContent: str,
					hasDynamicHeight
				};
			} else if (output.data['image/png']) {
				const image = document.createElement('img');
				image.src = `data:image/png;base64,${output.data['image/png']}`;
				display.appendChild(image);
				outputNode.appendChild(display);
				hasDynamicHeight = true;
			} else if (output.data['image/jpeg']) {
				const image = document.createElement('img');
				image.src = `data:image/jpeg;base64,${output.data['image/jpeg']}`;
				display.appendChild(image);
				outputNode.appendChild(display);
				hasDynamicHeight = true;
			} else if (output.data['text/plain']) {
				let data = output.data['text/plain'];
				let str = isArray(data) ? data.join('') : data;
				const contentNode = document.createElement('p');
				contentNode.innerText = str;
				outputNode.appendChild(contentNode);
			}<commit_msg>Support markdown in output<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as DOM from 'vs/base/browser/dom';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { RGBA, Color } from 'vs/base/common/color';
import { ansiColorIdentifiers } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry';
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import { isArray } from 'vs/base/common/types';
import { NotebookHandler } from 'vs/workbench/contrib/notebook/browser/cellRenderer';
import { IOutput } from 'vs/editor/common/modes';
import * as marked from 'vs/base/common/marked/marked';

export function registerMineTypeRenderer(types: string[], renderer: IMimeRenderer) {
	types.forEach(type => {
		MimeTypeRenderer.instance.register(type, renderer);
	});
}

export interface IRenderOutput {
	element: HTMLElement;
	whitespaceElement?: HTMLElement;
	shadowContent?: string;
	hasDynamicHeight: boolean;
}

interface IMimeRenderer {
	render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput;
}

export class MimeTypeRenderer {
	static instance = new MimeTypeRenderer();
	private readonly _renderers = new Map<string, IMimeRenderer>();

	register(type: string, renderer: IMimeRenderer) {
		this._renderers.set(type, renderer);
	}

	getRenderer(type: string) {
		return this._renderers.get(type);
	}

	static render(output: IOutput, themeService: IThemeService, webviewService: IWebviewService, notebookHandler?: NotebookHandler): IRenderOutput | null {
		return MimeTypeRenderer.instance.getRenderer(output.output_type)?.render(output, themeService, webviewService, notebookHandler) ?? null;
	}
}

registerMineTypeRenderer(['stream'], {
	render: (
		output: IOutput,
		themeService: IThemeService,
		webviewService: IWebviewService
	) => {
		const outputNode = document.createElement('div');
		const contentNode = document.createElement('p');
		contentNode.innerText = output.text;
		outputNode.appendChild(contentNode);
		return {
			element: outputNode,
			hasDynamicHeight: false
		};
	}
});

registerMineTypeRenderer(['error'], {
	render: (
		output: IOutput,
		themeService: IThemeService,
		webviewService: IWebviewService
	) => {
		const outputNode = document.createElement('div');
		const traceback = document.createElement('pre');
		DOM.addClasses(traceback, 'traceback');
		if (output.traceback) {
			for (let j = 0; j < output.traceback.length; j++) {
				traceback.appendChild(handleANSIOutput(output.traceback[j], themeService));
			}
		}
		outputNode.appendChild(traceback);
		return {
			element: outputNode,
			hasDynamicHeight: false
		};
	}
});

// Display Order
//
// application/json
// application/javascript
// text/html
// image/svg+xml
// text/markdown
// text/latex
// image/svg+xml
// image/gif
// image/png
// image/jpeg
// application/pdf
// text/plain

class RichDisplayRenderer implements IMimeRenderer {
	private _mdRenderer: marked.Renderer = new marked.Renderer({ gfm: true });;

	render(output: any, themeService: IThemeService, webviewService: IWebviewService, notebookHandler: NotebookHandler): IRenderOutput {
		const display = document.createElement('div');
		const outputNode = document.createElement('div');
		let hasDynamicHeight = false;
		DOM.addClasses(display, 'display');

		if (output.data) {
			if (output.data['text/html']) {
				let data = output.data['text/html'];
				let str = isArray(data) ? data.join('') : data;
				hasDynamicHeight = false;
				return {
					element: outputNode,
					shadowContent: str,
					hasDynamicHeight
				};
			} else if (output.data['text/markdown']) {
				let data = output.data['text/markdown'];
				const str = isArray(data) ? data.join('') : data;
				const mdOutput = document.createElement('div');
				mdOutput.innerHTML = marked(str, { renderer: this._mdRenderer });
				outputNode.appendChild(mdOutput);
				hasDynamicHeight = true;
			} else if (output.data['image/png']) {
				const image = document.createElement('img');
				image.src = `data:image/png;base64,${output.data['image/png']}`;
				display.appendChild(image);
				outputNode.appendChild(display);
				hasDynamicHeight = true;
			} else if (output.data['image/jpeg']) {
				const image = document.createElement('img');
				image.src = `data:image/jpeg;base64,${output.data['image/jpeg']}`;
				display.appendChild(image);
				outputNode.appendChild(display);
				hasDynamicHeight = true;
			} else if (output.data['text/plain']) {
				let data = output.data['text/plain'];
				let str = isArray(data) ? data.join('') : data;
				const contentNode = document.createElement('p');
				contentNode.innerText = str;
				outputNode.appendChild(contentNode);
			}
{'fraction_non_alphanumeric': 0.1662018386530317, 'fraction_numerical': 0.0010329511414110112, 'mean_word_length': 3.862882973380211, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4937965', 'n_tokens_mistral': 3078, 'n_tokens_neox': 2779, 'n_words': 598}