Skip to content

Commit 6d84d4e

Browse files
committed
fix #374
1 parent 95f4f0f commit 6d84d4e

File tree

5 files changed

+122
-92
lines changed

5 files changed

+122
-92
lines changed

packages/core/src/fields/button/ButtonActionRunner.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
type UpdateMetadataButtonAction,
2020
} from 'packages/core/src/config/ButtonConfig';
2121
import { MDLinkParser } from 'packages/core/src/parsers/MarkdownLinkParser';
22-
import { expectType, openURL } from 'packages/core/src/utils/Utils';
22+
import { expectType } from 'packages/core/src/utils/Utils';
2323
import { parseLiteral } from 'packages/core/src/utils/Literal';
2424
import { type NotePosition } from 'packages/core/src/config/APIConfigs';
2525
import { ErrorLevel, MetaBindJsError, MetaBindParsingError } from 'packages/core/src/utils/errors/MetaBindErrors';
@@ -250,12 +250,7 @@ export class ButtonActionRunner {
250250
}
251251

252252
async runOpenAction(action: OpenButtonAction, filePath: string): Promise<void> {
253-
const link = MDLinkParser.parseLinkOrUrl(action.link);
254-
if (link.internal) {
255-
this.plugin.internal.openFile(link.target, filePath, action.newTab ?? false);
256-
} else {
257-
openURL(link.target);
258-
}
253+
MDLinkParser.parseLinkOrUrl(action.link).open(this.plugin, filePath, action.newTab ?? false);
259254
}
260255

261256
async runInputAction(action: InputButtonAction): Promise<void> {

packages/core/src/fields/viewFields/fields/ImageVF.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ export class ImageVF extends AbstractViewField {
6767

6868
// we want the return value to be a human-readable string, since someone could save this to the frontmatter
6969
if (typeof content === 'string') {
70-
return MDLinkParser.convertToLinkString(content);
70+
return MDLinkParser.toLinkString(content);
7171
} else if (Array.isArray(content)) {
7272
const strings = content.filter(x => typeof x === 'string') as string[];
7373
return strings
74-
.map(x => MDLinkParser.convertToLinkString(x))
74+
.map(x => MDLinkParser.toLinkString(x))
7575
.filter(x => x !== '')
7676
.join(', ');
7777
} else {

packages/core/src/fields/viewFields/fields/LinkVF.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ export class LinkVF extends AbstractViewField {
6767

6868
// we want the return value to be a human-readable string, since someone could save this to the frontmatter
6969
if (typeof content === 'string') {
70-
return MDLinkParser.convertToLinkString(content);
70+
return MDLinkParser.toLinkString(content);
7171
} else if (Array.isArray(content)) {
7272
const strings = content.filter(x => typeof x === 'string') as string[];
7373
return strings
74-
.map(x => MDLinkParser.convertToLinkString(x))
74+
.map(x => MDLinkParser.toLinkString(x))
7575
.filter(x => x !== '')
7676
.join(', ');
7777
} else {

packages/core/src/parsers/MarkdownLinkParser.ts

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { type Parser } from '@lemons_dev/parsinom/lib/Parser';
22
import { P_UTILS } from '@lemons_dev/parsinom/lib/ParserUtils';
33
import { P } from '@lemons_dev/parsinom/lib/ParsiNOM';
44
import { runParser } from 'packages/core/src/parsers/ParsingError';
5-
import { isUrl } from 'packages/core/src/utils/Utils';
5+
import { isUrl, openURL } from 'packages/core/src/utils/Utils';
66
import { P_FilePath } from 'packages/core/src/parsers/nomParsers/GeneralNomParsers';
7+
import { type IPlugin } from 'packages/core/src/IPlugin';
78

89
const P_MDLinkInner: Parser<[string, string | undefined, string | undefined]> = P.sequence(
910
P_FilePath, // the file path
@@ -15,13 +16,7 @@ const P_MDLink: Parser<MarkdownLink> = P.or(
1516
// wiki links
1617
P.sequenceMap(
1718
(a, b): MarkdownLink => {
18-
return {
19-
isEmbed: a !== undefined,
20-
target: b[0],
21-
block: b[1],
22-
alias: b[2],
23-
internal: true,
24-
};
19+
return new MarkdownLink(a !== undefined, b[0], b[1], b[2], true);
2520
},
2621
P.string('!').optional(),
2722
P_MDLinkInner.wrapString('[[', ']]'),
@@ -31,13 +26,7 @@ const P_MDLink: Parser<MarkdownLink> = P.or(
3126
(a, b, c): MarkdownLink => {
3227
const internal = !isUrl(c);
3328

34-
return {
35-
isEmbed: a !== undefined,
36-
target: c,
37-
block: undefined,
38-
alias: b,
39-
internal: internal,
40-
};
29+
return new MarkdownLink(a !== undefined, c, undefined, b, internal);
4130
},
4231
P.string('!').optional(),
4332
P.manyNotOf('[]').wrapString('[', ']'),
@@ -47,12 +36,36 @@ const P_MDLink: Parser<MarkdownLink> = P.or(
4736

4837
const P_MDLinkList: Parser<MarkdownLink[]> = P.separateBy(P_MDLink, P.string(',').trim(P_UTILS.optionalWhitespace()));
4938

50-
export interface MarkdownLink {
39+
export class MarkdownLink {
5140
isEmbed: boolean;
5241
target: string;
5342
block?: string;
5443
alias?: string;
5544
internal: boolean;
45+
46+
constructor(isEmbed: boolean, target: string, block?: string, alias?: string, internal?: boolean) {
47+
this.isEmbed = isEmbed;
48+
this.target = target;
49+
this.block = block;
50+
this.alias = alias;
51+
this.internal = internal ?? true;
52+
}
53+
54+
static fromUrl(url: URL): MarkdownLink {
55+
return new MarkdownLink(false, url.href, undefined, url.hostname, false);
56+
}
57+
58+
fullTarget(): string {
59+
return this.block ? `${this.target}#${this.block}` : this.target;
60+
}
61+
62+
open(plugin: IPlugin, relativeFilePath: string, newTab: boolean): void {
63+
if (this.internal) {
64+
plugin.internal.openFile(this.fullTarget(), relativeFilePath, newTab);
65+
} else {
66+
openURL(this.target);
67+
}
68+
}
5669
}
5770

5871
export class MDLinkParser {
@@ -69,13 +82,7 @@ export class MDLinkParser {
6982
}
7083

7184
static urlToLink(url: URL): MarkdownLink {
72-
return {
73-
isEmbed: false,
74-
target: url.href,
75-
block: undefined,
76-
alias: url.hostname,
77-
internal: false,
78-
};
85+
return MarkdownLink.fromUrl(url);
7986
}
8087

8188
static parseLinkOrUrl(str: string): MarkdownLink {
@@ -86,7 +93,7 @@ export class MDLinkParser {
8693
}
8794
}
8895

89-
static convertToLinkString(str: string): string {
96+
static toLinkString(str: string): string {
9097
if (MDLinkParser.isLink(str)) {
9198
return str;
9299
} else if (isUrl(str)) {

tests/parserTests/MarkdownLinkParser.test.ts

Lines changed: 85 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,118 @@
11
import { describe, expect, test } from 'bun:test';
2-
import { MDLinkParser } from '../../packages/core/src/parsers/MarkdownLinkParser';
2+
import { MarkdownLink, MDLinkParser } from '../../packages/core/src/parsers/MarkdownLinkParser';
3+
4+
interface LinkObj {
5+
isEmbed: boolean;
6+
target: string;
7+
block?: string;
8+
alias?: string;
9+
internal: boolean;
10+
}
11+
12+
function toLink(obj: LinkObj): MarkdownLink {
13+
return new MarkdownLink(obj.isEmbed, obj.target, obj.block, obj.alias, obj.internal);
14+
}
315

416
describe('markdown link parser', () => {
517
describe('parse markdown link', () => {
618
// --- wiki links ---
719

820
test('should parse wiki link', () => {
9-
expect(MDLinkParser.parseLink('[[test]]')).toEqual({
10-
isEmbed: false,
11-
target: 'test',
12-
block: undefined,
13-
alias: undefined,
14-
internal: true,
15-
});
21+
expect(MDLinkParser.parseLink('[[test]]')).toEqual(
22+
toLink({
23+
isEmbed: false,
24+
target: 'test',
25+
block: undefined,
26+
alias: undefined,
27+
internal: true,
28+
}),
29+
);
1630
});
1731

1832
test('should parse wiki link embed', () => {
19-
expect(MDLinkParser.parseLink('![[test]]')).toEqual({
20-
isEmbed: true,
21-
target: 'test',
22-
block: undefined,
23-
alias: undefined,
24-
internal: true,
25-
});
33+
expect(MDLinkParser.parseLink('![[test]]')).toEqual(
34+
toLink({
35+
isEmbed: true,
36+
target: 'test',
37+
block: undefined,
38+
alias: undefined,
39+
internal: true,
40+
}),
41+
);
2642
});
2743

2844
test('should parse wiki with block', () => {
29-
expect(MDLinkParser.parseLink('[[test#123]]')).toEqual({
30-
isEmbed: false,
31-
target: 'test',
32-
block: '123',
33-
alias: undefined,
34-
internal: true,
35-
});
45+
expect(MDLinkParser.parseLink('[[test#123]]')).toEqual(
46+
toLink({
47+
isEmbed: false,
48+
target: 'test',
49+
block: '123',
50+
alias: undefined,
51+
internal: true,
52+
}),
53+
);
3654
});
3755

3856
test('should parse wiki with alias', () => {
39-
expect(MDLinkParser.parseLink('[[test|something]]')).toEqual({
40-
isEmbed: false,
41-
target: 'test',
42-
block: undefined,
43-
alias: 'something',
44-
internal: true,
45-
});
57+
expect(MDLinkParser.parseLink('[[test|something]]')).toEqual(
58+
toLink({
59+
isEmbed: false,
60+
target: 'test',
61+
block: undefined,
62+
alias: 'something',
63+
internal: true,
64+
}),
65+
);
4666
});
4767

4868
test('should parse wiki with block and alias', () => {
49-
expect(MDLinkParser.parseLink('[[test#123|something]]')).toEqual({
50-
isEmbed: false,
51-
target: 'test',
52-
block: '123',
53-
alias: 'something',
54-
internal: true,
55-
});
69+
expect(MDLinkParser.parseLink('[[test#123|something]]')).toEqual(
70+
toLink({
71+
isEmbed: false,
72+
target: 'test',
73+
block: '123',
74+
alias: 'something',
75+
internal: true,
76+
}),
77+
);
5678
});
5779

5880
// --- markdown links ---
5981

6082
test('should parse markdown link', () => {
61-
expect(MDLinkParser.parseLink('[something](test)')).toEqual({
62-
isEmbed: false,
63-
target: 'test',
64-
block: undefined,
65-
alias: 'something',
66-
internal: true,
67-
});
83+
expect(MDLinkParser.parseLink('[something](test)')).toEqual(
84+
toLink({
85+
isEmbed: false,
86+
target: 'test',
87+
block: undefined,
88+
alias: 'something',
89+
internal: true,
90+
}),
91+
);
6892
});
6993

7094
test('should parse markdown link embed', () => {
71-
expect(MDLinkParser.parseLink('![something](test)')).toEqual({
72-
isEmbed: true,
73-
target: 'test',
74-
block: undefined,
75-
alias: 'something',
76-
internal: true,
77-
});
95+
expect(MDLinkParser.parseLink('![something](test)')).toEqual(
96+
toLink({
97+
isEmbed: true,
98+
target: 'test',
99+
block: undefined,
100+
alias: 'something',
101+
internal: true,
102+
}),
103+
);
78104
});
79105

80106
test('should parse external markdown link', () => {
81-
expect(MDLinkParser.parseLink('[github](https://github.com)')).toEqual({
82-
isEmbed: false,
83-
target: 'https://github.com',
84-
block: undefined,
85-
alias: 'github',
86-
internal: false,
87-
});
107+
expect(MDLinkParser.parseLink('[github](https://github.com)')).toEqual(
108+
toLink({
109+
isEmbed: false,
110+
target: 'https://github.com',
111+
block: undefined,
112+
alias: 'github',
113+
internal: false,
114+
}),
115+
);
88116
});
89117

90118
// --- errors ---

0 commit comments

Comments
 (0)