mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Fix markdown link detection for links with titles (#151459)
Fixes #151458
This commit is contained in:
parent
677d79a4cd
commit
9545af80f6
|
@ -185,12 +185,12 @@ function stripAngleBrackets(link: string) {
|
|||
/**
|
||||
* Matches `[text](link)`
|
||||
*/
|
||||
const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*(".*?")?\)/g;
|
||||
const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*("[^"]*"|'[^']*'|\([^\(\)]*\))?\s*\)/g;
|
||||
|
||||
/**
|
||||
* Matches `[text](<link>)`
|
||||
*/
|
||||
const linkPatternAngle = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*<)(([^<>]|\([^\s\(\)]*?\))+)>\s*(".*?")?\)/g;
|
||||
const linkPatternAngle = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*<)(([^<>]|\([^\s\(\)]*?\))+)>\s*("[^"]*"|'[^']*'|\([^\(\)]*\))?\s*\)/g;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,14 @@ function createDiagnosticsManager(workspaceContents: MdWorkspaceContents, config
|
|||
return new DiagnosticManager(new DiagnosticComputer(engine, workspaceContents, linkProvider), configuration);
|
||||
}
|
||||
|
||||
function assertDiagnosticsEqual(actual: readonly vscode.Diagnostic[], expectedRanges: readonly vscode.Range[]) {
|
||||
assert.strictEqual(actual.length, expectedRanges.length);
|
||||
|
||||
for (let i = 0; i < actual.length; ++i) {
|
||||
assertRangeEqual(actual[i].range, expectedRanges[i], `Range ${i} to be equal`);
|
||||
}
|
||||
}
|
||||
|
||||
class MemoryDiagnosticConfiguration implements DiagnosticConfiguration {
|
||||
|
||||
private readonly _onDidChange = new vscode.EventEmitter<void>();
|
||||
|
@ -87,9 +95,10 @@ suite('markdown: Diagnostics', () => {
|
|||
));
|
||||
|
||||
const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc]));
|
||||
assert.deepStrictEqual(diagnostics.length, 2);
|
||||
assertRangeEqual(new vscode.Range(0, 6, 0, 22), diagnostics[0].range);
|
||||
assertRangeEqual(new vscode.Range(3, 11, 3, 27), diagnostics[1].range);
|
||||
assertDiagnosticsEqual(diagnostics, [
|
||||
new vscode.Range(0, 6, 0, 22),
|
||||
new vscode.Range(3, 11, 3, 27),
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should generate diagnostics for links to header that does not exist in current file', async () => {
|
||||
|
@ -103,9 +112,10 @@ suite('markdown: Diagnostics', () => {
|
|||
));
|
||||
|
||||
const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc]));
|
||||
assert.deepStrictEqual(diagnostics.length, 2);
|
||||
assertRangeEqual(new vscode.Range(2, 6, 2, 21), diagnostics[0].range);
|
||||
assertRangeEqual(new vscode.Range(5, 11, 5, 26), diagnostics[1].range);
|
||||
assertDiagnosticsEqual(diagnostics, [
|
||||
new vscode.Range(2, 6, 2, 21),
|
||||
new vscode.Range(5, 11, 5, 26),
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should generate diagnostics for links to non-existent headers in other files', async () => {
|
||||
|
@ -123,8 +133,9 @@ suite('markdown: Diagnostics', () => {
|
|||
));
|
||||
|
||||
const diagnostics = await getComputedDiagnostics(doc1, new InMemoryWorkspaceMarkdownDocuments([doc1, doc2]));
|
||||
assert.deepStrictEqual(diagnostics.length, 1);
|
||||
assertRangeEqual(new vscode.Range(5, 6, 5, 35), diagnostics[0].range);
|
||||
assertDiagnosticsEqual(diagnostics, [
|
||||
new vscode.Range(5, 6, 5, 35),
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should support links both with and without .md file extension', async () => {
|
||||
|
@ -150,8 +161,9 @@ suite('markdown: Diagnostics', () => {
|
|||
));
|
||||
|
||||
const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc]));
|
||||
assert.deepStrictEqual(diagnostics.length, 1);
|
||||
assertRangeEqual(new vscode.Range(1, 11, 1, 18), diagnostics[0].range);
|
||||
assertDiagnosticsEqual(diagnostics, [
|
||||
new vscode.Range(1, 11, 1, 18),
|
||||
]);
|
||||
});
|
||||
|
||||
test('Should not generate diagnostics when validate is disabled', async () => {
|
||||
|
@ -281,4 +293,24 @@ suite('markdown: Diagnostics', () => {
|
|||
const { diagnostics } = await manager.recomputeDiagnosticState(doc1, noopToken);
|
||||
assert.deepStrictEqual(diagnostics.length, 0);
|
||||
});
|
||||
|
||||
test('Should detect invalid links with titles', async () => {
|
||||
const doc = new InMemoryDocument(workspacePath('doc1.md'), joinLines(
|
||||
`[link](<no such.md> "text")`,
|
||||
`[link](<no such.md> 'text')`,
|
||||
`[link](<no such.md> (text))`,
|
||||
`[link](no-such.md "text")`,
|
||||
`[link](no-such.md 'text')`,
|
||||
`[link](no-such.md (text))`,
|
||||
));
|
||||
const diagnostics = await getComputedDiagnostics(doc, new InMemoryWorkspaceMarkdownDocuments([doc]));
|
||||
assertDiagnosticsEqual(diagnostics, [
|
||||
new vscode.Range(0, 8, 0, 18),
|
||||
new vscode.Range(1, 8, 1, 18),
|
||||
new vscode.Range(2, 8, 2, 18),
|
||||
new vscode.Range(3, 7, 3, 17),
|
||||
new vscode.Range(4, 7, 4, 17),
|
||||
new vscode.Range(5, 7, 5, 17),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -408,5 +408,22 @@ suite('markdown.DocumentLinkProvider', () => {
|
|||
assertLinksEqual(links, [new vscode.Range(0, 8, 0, 13)]);
|
||||
});
|
||||
|
||||
|
||||
test('Should find links with titles', async () => {
|
||||
const links = await getLinksForFile(joinLines(
|
||||
`[link](<no such.md> "text")`,
|
||||
`[link](<no such.md> 'text')`,
|
||||
`[link](<no such.md> (text))`,
|
||||
`[link](no-such.md "text")`,
|
||||
`[link](no-such.md 'text')`,
|
||||
`[link](no-such.md (text))`,
|
||||
));
|
||||
assertLinksEqual(links, [
|
||||
new vscode.Range(0, 8, 0, 18),
|
||||
new vscode.Range(1, 8, 1, 18),
|
||||
new vscode.Range(2, 8, 2, 18),
|
||||
new vscode.Range(3, 7, 3, 17),
|
||||
new vscode.Range(4, 7, 4, 17),
|
||||
new vscode.Range(5, 7, 5, 17),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue