Skip to content

Commit f7293b1

Browse files
Fix #974: restore proper handling of section-only wikilinks (#981)
1 parent 672eb6e commit f7293b1

File tree

3 files changed

+58
-23
lines changed

3 files changed

+58
-23
lines changed

packages/foam-vscode/src/core/services/markdown-link.test.ts

+17-19
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ describe('MarkdownLink', () => {
1212
.links[0];
1313
const parsed = MarkdownLink.analyzeLink(link);
1414
expect(parsed.target).toEqual('wikilink');
15-
expect(parsed.section).toBeUndefined();
16-
expect(parsed.alias).toBeUndefined();
15+
expect(parsed.section).toEqual('');
16+
expect(parsed.alias).toEqual('');
1717
});
1818
it('should parse target and section', () => {
1919
const link = parser.parse(
@@ -23,14 +23,14 @@ describe('MarkdownLink', () => {
2323
const parsed = MarkdownLink.analyzeLink(link);
2424
expect(parsed.target).toEqual('wikilink');
2525
expect(parsed.section).toEqual('section');
26-
expect(parsed.alias).toBeUndefined();
26+
expect(parsed.alias).toEqual('');
2727
});
2828
it('should parse target and alias', () => {
2929
const link = parser.parse(getRandomURI(), `this is a [[wikilink|alias]]`)
3030
.links[0];
3131
const parsed = MarkdownLink.analyzeLink(link);
3232
expect(parsed.target).toEqual('wikilink');
33-
expect(parsed.section).toBeUndefined();
33+
expect(parsed.section).toEqual('');
3434
expect(parsed.alias).toEqual('alias');
3535
});
3636
it('should parse links with square brackets #975', () => {
@@ -40,8 +40,8 @@ describe('MarkdownLink', () => {
4040
).links[0];
4141
const parsed = MarkdownLink.analyzeLink(link);
4242
expect(parsed.target).toEqual('wikilink [with] brackets');
43-
expect(parsed.section).toBeUndefined();
44-
expect(parsed.alias).toBeUndefined();
43+
expect(parsed.section).toEqual('');
44+
expect(parsed.alias).toEqual('');
4545
});
4646
it('should parse links with square brackets in alias #975', () => {
4747
const link = parser.parse(
@@ -50,7 +50,7 @@ describe('MarkdownLink', () => {
5050
).links[0];
5151
const parsed = MarkdownLink.analyzeLink(link);
5252
expect(parsed.target).toEqual('wikilink');
53-
expect(parsed.section).toBeUndefined();
53+
expect(parsed.section).toEqual('');
5454
expect(parsed.alias).toEqual('alias [with] brackets');
5555
});
5656
it('should parse target and alias with escaped separator', () => {
@@ -60,7 +60,7 @@ describe('MarkdownLink', () => {
6060
).links[0];
6161
const parsed = MarkdownLink.analyzeLink(link);
6262
expect(parsed.target).toEqual('wikilink');
63-
expect(parsed.section).toBeUndefined();
63+
expect(parsed.section).toEqual('');
6464
expect(parsed.alias).toEqual('alias');
6565
});
6666
it('should parse target section and alias', () => {
@@ -77,9 +77,9 @@ describe('MarkdownLink', () => {
7777
const link = parser.parse(getRandomURI(), `this is a [[#section]]`)
7878
.links[0];
7979
const parsed = MarkdownLink.analyzeLink(link);
80-
expect(parsed.target).toBeUndefined();
80+
expect(parsed.target).toEqual('');
8181
expect(parsed.section).toEqual('section');
82-
expect(parsed.alias).toBeUndefined();
82+
expect(parsed.alias).toEqual('');
8383
});
8484
});
8585

@@ -89,7 +89,7 @@ describe('MarkdownLink', () => {
8989
.links[0];
9090
const parsed = MarkdownLink.analyzeLink(link);
9191
expect(parsed.target).toEqual('to/path.md');
92-
expect(parsed.section).toBeUndefined();
92+
expect(parsed.section).toEqual('');
9393
expect(parsed.alias).toEqual('link');
9494
});
9595
it('should parse target and section', () => {
@@ -109,7 +109,7 @@ describe('MarkdownLink', () => {
109109
range: Range.create(0, 0),
110110
};
111111
const parsed = MarkdownLink.analyzeLink(link);
112-
expect(parsed.target).toBeUndefined();
112+
expect(parsed.target).toEqual('');
113113
expect(parsed.section).toEqual('section');
114114
expect(parsed.alias).toEqual('link');
115115
});
@@ -120,17 +120,15 @@ describe('MarkdownLink', () => {
120120
).links[0];
121121
const parsed = MarkdownLink.analyzeLink(link);
122122
expect(parsed.target).toEqual('to/path.md');
123-
expect(parsed.section).toBeUndefined();
123+
expect(parsed.section).toEqual('');
124124
expect(parsed.alias).toEqual('inbox [xyz]');
125125
});
126-
it('should parse links with empty label #975', () => {
127-
const link = parser.parse(
128-
getRandomURI(),
129-
`this is a [](to/path.md)`
130-
).links[0];
126+
it('should parse links with empty label #975', () => {
127+
const link = parser.parse(getRandomURI(), `this is a [](to/path.md)`)
128+
.links[0];
131129
const parsed = MarkdownLink.analyzeLink(link);
132130
expect(parsed.target).toEqual('to/path.md');
133-
expect(parsed.section).toBeUndefined();
131+
expect(parsed.section).toEqual('');
134132
expect(parsed.alias).toEqual('');
135133
});
136134
});

packages/foam-vscode/src/core/services/markdown-link.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@ export abstract class MarkdownLink {
1212
if (link.type === 'wikilink') {
1313
const [, target, section, alias] = this.wikilinkRegex.exec(link.rawText);
1414
return {
15-
target: target?.replace(/\\/g, ''),
16-
section,
17-
alias,
15+
target: target?.replace(/\\/g, '') ?? '',
16+
section: section ?? '',
17+
alias: alias ?? '',
1818
};
1919
}
2020
if (link.type === 'link') {
2121
const [, alias, target, section] = this.directLinkRegex.exec(
2222
link.rawText
2323
);
24-
return { target, section, alias };
24+
return {
25+
target: target ?? '',
26+
section: section ?? '',
27+
alias: alias ?? '',
28+
};
2529
}
2630
throw new Error(
2731
`Unexpected state: link of type ${link.type} is not supported`

packages/foam-vscode/src/core/services/markdown-provider.test.ts

+33
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,39 @@ describe('Link resolution', () => {
147147
expect(ws.resolveLink(noteA, noteA.links[1])).toEqual(noteC.uri);
148148
expect(ws.resolveLink(noteA, noteA.links[2])).toEqual(noteD.uri);
149149
});
150+
151+
it('should resolve wikilink with section identifier', () => {
152+
const noteA = createTestNote({
153+
uri: '/path/to/page-a.md',
154+
links: [
155+
// uppercased filename, lowercased slug
156+
{ slug: 'page-b#section' },
157+
],
158+
});
159+
const noteB = createTestNote({ uri: '/somewhere/PAGE-B.md' });
160+
const ws = createTestWorkspace()
161+
.set(noteA)
162+
.set(noteB);
163+
164+
expect(ws.resolveLink(noteA, noteA.links[0])).toEqual(
165+
noteB.uri.withFragment('section')
166+
);
167+
});
168+
169+
it('should resolve section-only wikilinks', () => {
170+
const noteA = createTestNote({
171+
uri: '/path/to/page-a.md',
172+
links: [
173+
// uppercased filename, lowercased slug
174+
{ slug: '#section' },
175+
],
176+
});
177+
const ws = createTestWorkspace().set(noteA);
178+
179+
expect(ws.resolveLink(noteA, noteA.links[0])).toEqual(
180+
noteA.uri.withFragment('section')
181+
);
182+
});
150183
});
151184

152185
describe('Markdown direct links', () => {

0 commit comments

Comments
 (0)