Files
azuredatastudio/extensions/markdown/src/documentLinkProvider.ts

64 lines
2.1 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as path from 'path';
export default class MarkdownDocumentLinkProvider implements vscode.DocumentLinkProvider {
private _linkPattern = /(\[[^\]]*\]\(\s*?)(((((?=.*\)\)+)|(?=.*\)\]+))[^\s\)]+?)|([^\s]+)))\)/g;
constructor() { }
public provideDocumentLinks(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.DocumentLink[] {
const results: vscode.DocumentLink[] = [];
const base = path.dirname(document.uri.fsPath);
const text = document.getText();
this._linkPattern.lastIndex = 0;
let match: RegExpMatchArray | null;
while ((match = this._linkPattern.exec(text))) {
const pre = match[1];
const link = match[2];
const offset = (match.index || 0) + pre.length;
const linkStart = document.positionAt(offset);
const linkEnd = document.positionAt(offset + link.length);
try {
results.push(new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
this.normalizeLink(document, link, base)));
} catch (e) {
// noop
}
}
return results;
}
private normalizeLink(document: vscode.TextDocument, link: string, base: string): vscode.Uri {
const uri = vscode.Uri.parse(link);
if (uri.scheme) {
return uri;
}
// assume it must be a file
let resourcePath = uri.path;
if (!uri.path) {
resourcePath = document.uri.path;
} else if (uri.path[0] === '/') {
const root = vscode.workspace.getWorkspaceFolder(document.uri);
if (root) {
resourcePath = path.join(root.uri.fsPath, uri.path);
}
} else {
resourcePath = path.join(base, uri.path);
}
return vscode.Uri.parse(`command:_markdown.openDocumentLink?${encodeURIComponent(JSON.stringify({ fragment: uri.fragment, path: resourcePath }))}`);
}
}