提交 d4116a8f 编写于 作者: J Johannes Rieken

tweak markdown string conversion and rendering

上级 0b998674
......@@ -11,6 +11,7 @@ import * as marked from 'vs/base/common/marked/marked';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { IDisposable } from 'vs/base/common/lifecycle';
import { onUnexpectedError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
export interface IContentActionHandler {
callback: (content: string, event?: IMouseEvent) => void;
......@@ -52,6 +53,14 @@ export function renderFormattedText(formattedText: string, options: RenderOption
export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions = {}): HTMLElement {
const element = createElement(options);
const _href = function (href: string): string {
const data = markdown.uris && markdown.uris[href];
if (data) {
href = URI.revive(data).toString(true);
}
return href;
};
// signal to code-block render that the
// element has been created
let signalInnerHTML: Function;
......@@ -59,6 +68,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions
const renderer = new marked.Renderer();
renderer.image = (href: string, title: string, text: string) => {
href = _href(href);
let dimensions: string[] = [];
if (href) {
const splitted = href.split('|').map(s => s.trim());
......@@ -99,6 +109,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: RenderOptions
if (href === text) { // raw link case
text = removeMarkdownEscapes(text);
}
href = _href(href);
title = removeMarkdownEscapes(title);
href = removeMarkdownEscapes(href);
if (
......
......@@ -4,10 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import { equals } from 'vs/base/common/arrays';
import { UriComponents } from 'vs/base/common/uri';
export interface IMarkdownString {
value: string;
isTrusted?: boolean;
uris?: { [href: string]: UriComponents };
}
export class MarkdownString implements IMarkdownString {
......
......@@ -392,9 +392,13 @@ declare namespace monaco {
static readonly WinCtrl: number;
static chord(firstPart: number, secondPart: number): number;
}
export interface IMarkdownString {
value: string;
isTrusted?: boolean;
uris?: {
[href: string]: UriComponents;
};
}
export interface IKeyboardEvent {
......
......@@ -274,12 +274,6 @@ export interface ISerializedSignatureHelpProviderMetadata {
readonly retriggerCharacters: ReadonlyArray<string>;
}
export interface IMarkdownStringDto {
isTrusted: boolean;
value: string;
uris: { [n: string]: UriComponents };
}
export interface MainThreadLanguageFeaturesShape extends IDisposable {
$unregister(handle: number): void;
$registerOutlineSupport(handle: number, selector: ISerializedDocumentFilter[], extensionId: string): void;
......
......@@ -19,7 +19,7 @@ import { IRange } from 'vs/editor/common/core/range';
import { ISelection } from 'vs/editor/common/core/selection';
import * as htmlContent from 'vs/base/common/htmlContent';
import * as languageSelector from 'vs/editor/common/modes/languageSelector';
import { WorkspaceEditDto, ResourceTextEditDto, ResourceFileEditDto, IMarkdownStringDto } from 'vs/workbench/api/node/extHost.protocol';
import { WorkspaceEditDto, ResourceTextEditDto, ResourceFileEditDto } from 'vs/workbench/api/node/extHost.protocol';
import { MarkerSeverity, IRelatedInformation, IMarkerData, MarkerTag } from 'vs/platform/markers/common/markers';
import { ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/node/extHostDocumentsAndEditors';
......@@ -210,38 +210,32 @@ export namespace MarkdownString {
}
export function from(markup: vscode.MarkdownString | vscode.MarkedString): htmlContent.IMarkdownString {
let res: htmlContent.IMarkdownString;
if (isCodeblock(markup)) {
const { language, value } = markup;
return { value: '```' + language + '\n' + value + '\n```\n' };
res = { value: '```' + language + '\n' + value + '\n```\n' };
} else if (htmlContent.isMarkdownString(markup)) {
return markup;
res = markup;
} else if (typeof markup === 'string') {
return { value: <string>markup };
res = { value: <string>markup };
} else {
return { value: '' };
res = { value: '' };
}
}
export function from2(markup: vscode.MarkedString | vscode.MarkdownString): IMarkdownStringDto {
let { value, isTrusted } = from(markup);
let uris = Object.create(null);
// extract uris into a separate object
res.uris = Object.create(null);
let renderer = new marked.Renderer();
renderer.image = renderer.link = (href: string): string => {
try {
uris[href] = URI.parse(href, true);
res.uris[href] = URI.parse(href, true);
} catch (e) {
// ignore
}
return '';
};
marked(value, { renderer });
return {
isTrusted,
value,
uris
};
marked(res.value, { renderer });
return res;
}
export function to(value: htmlContent.IMarkdownString): vscode.MarkdownString {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { MarkdownString } from 'vs/workbench/api/node/extHostTypeConverters';
import { isEmptyObject } from 'vs/base/common/types';
import { size } from 'vs/base/common/collections';
suite('ExtHostTypeConverter', function () {
test('MarkdownConvert - uris', function () {
let data = MarkdownString.from('Hello');
assert.equal(isEmptyObject(data.uris), true);
assert.equal(data.value, 'Hello');
data = MarkdownString.from('Hello [link](foo)');
assert.equal(data.value, 'Hello [link](foo)');
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri
data = MarkdownString.from('Hello [link](www.noscheme.bad)');
assert.equal(data.value, 'Hello [link](www.noscheme.bad)');
assert.equal(isEmptyObject(data.uris), true); // no scheme, no uri
data = MarkdownString.from('Hello [link](foo:path)');
assert.equal(data.value, 'Hello [link](foo:path)');
assert.equal(size(data.uris), 1);
assert.ok(!!data.uris['foo:path']);
data = MarkdownString.from('hello@foo.bar');
assert.equal(data.value, 'hello@foo.bar');
assert.equal(size(data.uris), 1);
assert.ok(!!data.uris['mailto:hello@foo.bar']);
data = MarkdownString.from('*hello* [click](command:me)');
assert.equal(data.value, '*hello* [click](command:me)');
assert.equal(size(data.uris), 1);
assert.ok(!!data.uris['command:me']);
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
assert.equal(size(data.uris), 1);
assert.ok(!!data.uris['file:///somepath/here']);
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here)');
assert.equal(size(data.uris), 1);
assert.ok(!!data.uris['file:///somepath/here']);
data = MarkdownString.from('*hello* [click](file:///somepath/here). [click](file:///somepath/here2)');
assert.equal(data.value, '*hello* [click](file:///somepath/here). [click](file:///somepath/here2)');
assert.equal(size(data.uris), 2);
assert.ok(!!data.uris['file:///somepath/here']);
assert.ok(!!data.uris['file:///somepath/here2']);
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册