Skip to content

Commit 55ed8ca

Browse files
committed
fix: Convert Notion's "mention" style links to internal pages, sillsdev#97
1 parent 9d11a98 commit 55ed8ca

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

src/plugins/internalLinks.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,48 @@ test("urls that show up as raw text get left that way", async () => {
3131
expect(results.trim()).toBe("https://github.com");
3232
});
3333

34+
// See https://github.com/sillsdev/docu-notion/issues/97
35+
test("mention-style link to an existing page", async () => {
36+
const targetPageId = "123";
37+
const targetPage: NotionPage = makeSamplePageObject({
38+
slug: undefined,
39+
name: "Hello World",
40+
id: targetPageId,
41+
});
42+
43+
const results = await getMarkdown(
44+
{
45+
type: "paragraph",
46+
paragraph: {
47+
rich_text: [
48+
{
49+
type: "mention",
50+
mention: {
51+
type: "page",
52+
page: {
53+
id: `${targetPageId}`,
54+
},
55+
},
56+
annotations: {
57+
bold: false,
58+
italic: false,
59+
strikethrough: false,
60+
underline: false,
61+
code: false,
62+
color: "default",
63+
},
64+
plain_text: "foo",
65+
href: `https://www.notion.so/${targetPageId}`,
66+
},
67+
],
68+
color: "default",
69+
},
70+
},
71+
targetPage
72+
);
73+
expect(results.trim()).toBe(`[foo](/${targetPageId})`);
74+
});
75+
3476
test("link to an existing page on this site that has no slug", async () => {
3577
const targetPageId = "123";
3678
const targetPage: NotionPage = makeSamplePageObject({

src/plugins/internalLinks.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ function convertInternalLink(
4040
context: IDocuNotionContext,
4141
markdownLink: string
4242
): string {
43-
const linkRegExp = /\[([^\]]+)?\]\(\/?([^),^/]+)\)/g;
43+
// match both [foo](/123) and [bar](https://www.notion.so/123) <-- the "mention" link style
44+
const linkRegExp =
45+
/\[([^\]]+)?\]\((?:https?:\/\/www\.notion\.so\/|\/)?([^),^/]+)\)/g;
4446
const match = linkRegExp.exec(markdownLink);
4547
if (match === null) {
4648
warning(
@@ -125,7 +127,10 @@ export const standardInternalLinkConversion: IPlugin = {
125127
// (has some other text that's been turned into a link) or "raw".
126128
// Raw links come in without a leading slash, e.g. [link_to_page](4a6de8c0-b90b-444b-8a7b-d534d6ec71a4)
127129
// Inline links come in with a leading slash, e.g. [pointer to the introduction](/4a6de8c0b90b444b8a7bd534d6ec71a4)
128-
match: /\[([^\]]+)?\]\((?!mailto:)(\/?[^),^/]+)\)/,
130+
// "Mention" links come in as full URLs, e.g. [link_to_page](https://www.notion.so/62f1187010214b0883711a1abb277d31)
131+
// YOu can create them either with @+the name of a page, or by pasting a URL and then selecting the "Mention" option.
132+
match:
133+
/\[([^\]]+)?\]\((?!mailto:)(https:\/\/www\.notion\.so\/[^),^/]+|\/?[^),^/]+)\)/,
129134
convert: convertInternalLink,
130135
},
131136
};

src/pull.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ async function getPagesRecursively(
216216
pageInfo.childPageIdsAndOrder.length
217217
) {
218218
error(
219-
`Skipping "${pageInTheOutline.nameOrTitle}" and its children. docu-notion does not support pages that are both levels and have content at the same time.`
219+
`Skipping "${pageInTheOutline.nameOrTitle}" and its children. docu-notion does not support pages that are both levels and have text content (paragraphs) at the same time. Normally outline pages should just be composed of 1) links to other pages and 2) child pages (other levels of the outline). Note that @-mention style links appear as text paragraphs to docu-notion so must not be used to form the outline.`
220220
);
221221
++counts.skipped_because_level_cannot_have_content;
222222
return;

0 commit comments

Comments
 (0)