Skip to content

Commit 522d1bb

Browse files
committed
Merge branch 'main' into release
2 parents 581f0f0 + f1176c5 commit 522d1bb

File tree

5 files changed

+134
-8
lines changed

5 files changed

+134
-8
lines changed

Diff for: src/plugins/internalLinks.spec.ts

+122-2
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({
@@ -564,9 +606,87 @@ test("internal link inside codeblock ignored", async () => {
564606
);
565607
});
566608

609+
test("multiple internal links in a paragraph", async () => {
610+
const targetPageAId = "123";
611+
const targetPageA: NotionPage = makeSamplePageObject({
612+
slug: undefined,
613+
name: "Hello World A",
614+
id: targetPageAId,
615+
});
616+
const targetPageBId = "456";
617+
const targetPageB: NotionPage = makeSamplePageObject({
618+
slug: undefined,
619+
name: "Hello World B",
620+
id: targetPageBId,
621+
});
622+
623+
const results = await getMarkdown(
624+
{
625+
type: "paragraph",
626+
paragraph: {
627+
rich_text: [
628+
{
629+
type: "text",
630+
text: {
631+
content: "A",
632+
link: { url: `/${targetPageAId}` },
633+
},
634+
annotations: {
635+
bold: false,
636+
italic: false,
637+
strikethrough: false,
638+
underline: false,
639+
code: false,
640+
color: "default",
641+
},
642+
plain_text: "A",
643+
href: `/${targetPageAId}`,
644+
},
645+
{
646+
type: "text",
647+
text: { content: " ", link: null },
648+
annotations: {
649+
bold: false,
650+
italic: false,
651+
strikethrough: false,
652+
underline: false,
653+
code: false,
654+
color: "default",
655+
},
656+
plain_text: " ",
657+
href: null,
658+
},
659+
{
660+
type: "text",
661+
text: {
662+
content: "B",
663+
link: { url: `/${targetPageBId}` },
664+
},
665+
annotations: {
666+
bold: false,
667+
italic: false,
668+
strikethrough: false,
669+
underline: false,
670+
code: false,
671+
color: "default",
672+
},
673+
plain_text: "B",
674+
href: `/${targetPageBId}`,
675+
},
676+
],
677+
color: "default",
678+
},
679+
},
680+
targetPageA,
681+
targetPageB
682+
);
683+
expect(results.trim()).toBe(`[A](/${targetPageAId}) [B](/${targetPageBId})`);
684+
});
685+
567686
async function getMarkdown(
568687
block: Record<string, unknown>,
569-
targetPage?: NotionPage
688+
targetPage?: NotionPage,
689+
targetPage2?: NotionPage
570690
) {
571691
const config = {
572692
plugins: [
@@ -575,5 +695,5 @@ async function getMarkdown(
575695
standardExternalLinkConversion,
576696
],
577697
};
578-
return await oneBlockToMarkdown(config, block, targetPage);
698+
return await oneBlockToMarkdown(config, block, targetPage, targetPage2);
579699
}

Diff for: src/plugins/internalLinks.ts

+7-2
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
};

Diff for: src/plugins/pluginTestRun.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ export function makeSamplePageObject(options: {
241241
export async function oneBlockToMarkdown(
242242
config: IDocuNotionConfig,
243243
block: Record<string, unknown>,
244-
targetPage?: NotionPage
244+
targetPage?: NotionPage,
245+
targetPage2?: NotionPage
245246
): Promise<string> {
246247
// just in case someone expects these other properties that aren't normally relevant,
247248
// we merge the given block properties into an actual, full block
@@ -280,6 +281,6 @@ export async function oneBlockToMarkdown(
280281
return await blocksToMarkdown(
281282
config,
282283
[fullBlock as NotionBlock],
283-
targetPage ? [dummyPage1, targetPage, dummyPage2] : undefined
284+
targetPage ? [dummyPage1, targetPage, targetPage2 ?? dummyPage2] : undefined
284285
);
285286
}

Diff for: src/pull.ts

+1-1
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;

Diff for: src/transform.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ function doLinkFixes(
189189
markdown: string,
190190
config: IDocuNotionConfig
191191
): string {
192-
const linkRegExp = /\[.*\]\([^\)]*\)/g;
192+
const linkRegExp = /\[.*?\]\([^\)]*?\)/g;
193193

194194
logDebug("markdown before link fixes", markdown);
195195
let match: RegExpExecArray | null;

0 commit comments

Comments
 (0)