Don't treat escaped markdown reference links as links (#149407)

Fixes #149406

Make sure that escaping the leading `[` of a reference link means it is not considered a link

- Picks up new grammar with fixes
- Updates our document link provider to also not consider these as link
This commit is contained in:
Matt Bierner 2022-05-12 19:35:36 -07:00 committed by GitHub
parent 9e8b4e53ba
commit 113287ccc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 13 deletions

View file

@ -33,7 +33,7 @@
"git": {
"name": "microsoft/vscode-markdown-tm-grammar",
"repositoryUrl": "https://github.com/microsoft/vscode-markdown-tm-grammar",
"commitHash": "b068fcb2fbfa834e695505bfb02bbcc0b4edab8b"
"commitHash": "09c3e715102d08bba4c4ea828634474fc58b6f57"
}
},
"license": "MIT",

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/b068fcb2fbfa834e695505bfb02bbcc0b4edab8b",
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/09c3e715102d08bba4c4ea828634474fc58b6f57",
"name": "Markdown",
"scopeName": "text.html.markdown",
"patterns": [
@ -2838,7 +2838,7 @@
"name": "punctuation.definition.constant.end.markdown"
}
},
"match": "(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])(\\[)([^\\]]*+)(\\])",
"match": "(?<![\\]\\\\])(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])(\\[)([^\\]]*+)(\\])",
"name": "meta.link.reference.markdown"
},
"link-ref-literal": {
@ -2859,7 +2859,7 @@
"name": "punctuation.definition.constant.end.markdown"
}
},
"match": "(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(\\])",
"match": "(?<![\\]\\\\])(\\[)((?<square>[^\\[\\]\\\\]|\\\\.|\\[\\g<square>*+\\])*+)(\\])[ ]?(\\[)(\\])",
"name": "meta.link.reference.literal.markdown"
},
"link-ref-shortcut": {
@ -2874,7 +2874,7 @@
"name": "punctuation.definition.link.title.end.markdown"
}
},
"match": "(\\[)(\\S+?)(\\])",
"match": "(?<![\\]\\\\])(\\[)(\\S+?)(\\])",
"name": "meta.link.reference.markdown"
},
"raw": {

View file

@ -166,9 +166,9 @@ function stripAngleBrackets(link: string) {
const linkPattern = /(\[((!\[[^\]]*?\]\(\s*)([^\s\(\)]+?)\s*\)\]|(?:\\\]|[^\]])*\])\(\s*)(([^\s\(\)]|\([^\s\(\)]*?\))+)\s*(".*?")?\)/g;
/**
* Matches `[text][ref]`
* Matches `[text][ref]` or `[shorthand]`
*/
const referenceLinkPattern = /(?:(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]|\[\s*?([^\s\]]*?)\])(?![\:\(])/g;
const referenceLinkPattern = /(^|[^\]\\])(?:(?:(\[((?:\\\]|[^\]])+)\]\[\s*?)([^\s\]]*?)\]|\[\s*?([^\s\]]*?)\])(?![\:\(]))/gm;
/**
* Matches `<http://example.com>`
@ -318,15 +318,15 @@ export class MdLinkProvider implements vscode.DocumentLinkProvider {
for (const match of text.matchAll(referenceLinkPattern)) {
let linkStart: vscode.Position;
let linkEnd: vscode.Position;
let reference = match[3];
let reference = match[4];
if (reference) { // [text][ref]
const pre = match[1];
const offset = (match.index || 0) + pre.length;
const pre = match[2];
const offset = ((match.index ?? 0) + match[1].length) + pre.length;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + reference.length);
} else if (match[4]) { // [ref][], [ref]
reference = match[4];
const offset = (match.index || 0) + 1;
} else if (match[5]) { // [ref][], [ref]
reference = match[5];
const offset = ((match.index ?? 0) + match[1].length) + 1;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + reference.length);
} else {

View file

@ -172,6 +172,16 @@ suite('markdown.DocumentLinkProvider', () => {
assert.strictEqual(links.length, 0);
});
test('Should not include reference links with escaped leading brackets', async () => {
const links = await getLinksForFile(joinLines(
`\\[bad link][good]`,
`\\[good]`,
`[good]: http://example.com`,
));
assert.strictEqual(links.length, 1);
assertRangeEqual(links[0].range, new vscode.Range(2, 8, 2, 26)); // Should only find the definition
});
test('Should not consider links in code fenced with backticks', async () => {
const links = await getLinksForFile(joinLines(
'```',