Skip to content

Commit 3182aca

Browse files
committed
convert all former "Docusaurus Tweaks" to plugins with minimal unit tests
1 parent 2988b70 commit 3182aca

File tree

7 files changed

+166
-133
lines changed

7 files changed

+166
-133
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
"eslint-plugin-prettier": "^3.4.0",
8080
"jest": "^28.1.3",
8181
"lint-staged": "^10.5.4",
82+
"patch-package": "^6.5.1",
8283
"prettier": "^2.2.1",
8384
"semantic-release": "^19.0.2",
8485
"ts-jest": "^28.0.7",

src/DocusaurusTweaks.ts

Lines changed: 0 additions & 115 deletions
This file was deleted.

src/config/default.docunotion.config.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { imgurGifTweak } from "../DocusaurusTweaks";
1+
import {
2+
gifEmbed,
3+
imgurGifEmbed,
4+
vimeoEmbed,
5+
youtubeEmbed,
6+
} from "../DocusaurusEmbeds";
27
import { standardImageTransformer } from "../images";
38
import { standardLinkConversion } from "../plugins/internalLinks";
49
import { standardCalloutTransformer } from "../plugins/CalloutTransformer";
@@ -16,20 +21,23 @@ const defaultConfig: IDocuNotionConfig = {
1621
escapeHtmlBlockModifier,
1722
standardHeadingTransformer, // does operations on both the Notion JSON and then later, on the notion to markdown transform
1823

19-
// Notion to Markdown transformers
24+
// Notion to Markdown transformers. Most things get transformed correctly by the notion-to-markdown library,
25+
// but some things need special handling.
2026
standardColumnTransformer,
2127
standardColumnListTransformer,
2228
standardImageTransformer,
2329
standardCalloutTransformer,
2430
standardTableTransformer,
2531
standardNumberedListTransformer,
2632

27-
// Link modifiers, which are special because they can read all the pages
33+
// Link modifiers, which are special because they can read metadata from all the pages in order to figure out the correct url
2834
standardLinkConversion,
2935

30-
// Regexps that operate on the Markdown output
31-
imgurGifTweak,
32-
// TODO: add the rest of the existing ones
36+
// Regexps plus javascript `import`s that operate on the Markdown output
37+
imgurGifEmbed,
38+
gifEmbed,
39+
youtubeEmbed,
40+
vimeoEmbed,
3341
],
3442
};
3543

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { NotionBlock } from "../config/configuration";
2+
import { setLogLevel } from "../log";
3+
import { blocksToMarkdown } from "../TestRun";
4+
import {
5+
gifEmbed,
6+
imgurGifEmbed,
7+
vimeoEmbed,
8+
youtubeEmbed,
9+
} from "./StandardEmbeddings";
10+
11+
test("youtube", async () => {
12+
const config = { plugins: [youtubeEmbed] };
13+
const result = await blocksToMarkdown(config, [
14+
{
15+
object: "block",
16+
id: "e6ddd1d4-36d4-4925-94c1-5dff4662c1f3",
17+
has_children: false,
18+
archived: false,
19+
type: "video",
20+
video: {
21+
caption: [
22+
{
23+
type: "text",
24+
text: {
25+
content: "A video about editing in Notion",
26+
link: null,
27+
},
28+
plain_text: "A video about editing in Notion",
29+
href: null,
30+
},
31+
],
32+
type: "external",
33+
external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
34+
},
35+
} as unknown as NotionBlock,
36+
]);
37+
expect(result).toContain(`import ReactPlayer from "react-player";`);
38+
expect(result).toContain(
39+
`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`
40+
);
41+
});
42+
43+
test("vimeo", async () => {
44+
setLogLevel("verbose");
45+
const config = { plugins: [vimeoEmbed] };
46+
const result = await blocksToMarkdown(config, [
47+
{
48+
object: "block",
49+
id: "39ff83a3-2fb5-4411-a715-960656a177ff",
50+
type: "video",
51+
video: {
52+
caption: [],
53+
type: "external",
54+
external: { url: "https://vimeo.com/4613611xx" },
55+
},
56+
} as unknown as NotionBlock,
57+
]);
58+
expect(result).toContain(`import ReactPlayer from "react-player";`);
59+
expect(result).toContain(
60+
`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`
61+
);
62+
});
63+
64+
test("imgur", async () => {
65+
setLogLevel("verbose");
66+
const config = { plugins: [imgurGifEmbed] };
67+
const result = await blocksToMarkdown(config, [
68+
{
69+
object: "block",
70+
id: "e36710d8-98ad-40dc-b41b-b376ebdd6894",
71+
type: "bookmark",
72+
bookmark: { caption: [], url: "https://imgur.com/gallery/U8TTNuI" },
73+
} as unknown as NotionBlock,
74+
]);
75+
expect(result.trim()).toBe(`![](https://imgur.com/gallery/U8TTNuI.gif)`);
76+
});
77+
78+
test("gif", async () => {
79+
setLogLevel("verbose");
80+
const config = { plugins: [gifEmbed] };
81+
const result = await blocksToMarkdown(config, [
82+
{
83+
object: "block",
84+
id: "e36710d8-98ad-40dc-b41b-b376ebdd6894",
85+
type: "bookmark",
86+
bookmark: {
87+
caption: [],
88+
url: "https://en.wikipedia.org/wiki/GIF#/media/File:Rotating_earth_(large).gif",
89+
},
90+
} as unknown as NotionBlock,
91+
]);
92+
expect(result.trim()).toBe(
93+
`![](https://en.wikipedia.org/wiki/GIF#/media/File:Rotating_earth_(large).gif)`
94+
);
95+
});

src/plugins/StandardEmbeddings.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { IPlugin } from "../config/configuration";
2+
3+
export const gifEmbed: IPlugin = {
4+
name: "gif",
5+
regexMarkdownModifications: [
6+
{
7+
label: "gif",
8+
// I once saw a gif coming from Notion that wasn't a full
9+
// url, which wouldn't work, hence the "http" requirement
10+
regex: /\[.*\]\((http.*(\.(gif|GIF)))\)/gm,
11+
output: `![]($1)`,
12+
},
13+
],
14+
};
15+
16+
export const imgurGifEmbed: IPlugin = {
17+
name: "imgur",
18+
regexMarkdownModifications: [
19+
{
20+
label: "imgur",
21+
regex: /\[.*\]\((.*imgur\.com\/.*)\)/gm, // imgur.com
22+
// imgur links to gifs need a .gif at the end, but the url they give you doesn't have one.
23+
output: `![]($1.gif)`,
24+
},
25+
],
26+
};
27+
export const youtubeEmbed: IPlugin = {
28+
name: "youtube",
29+
regexMarkdownModifications: [
30+
{
31+
label: "youtube",
32+
regex: /\[.*\]\((.*youtube\.com\/watch.*)\)/gm, //youtube.com/watch
33+
imports: [`import ReactPlayer from "react-player";`],
34+
output: `<ReactPlayer controls url="$1" />`,
35+
},
36+
],
37+
};
38+
export const vimeoEmbed: IPlugin = {
39+
name: "vimeo",
40+
regexMarkdownModifications: [
41+
{
42+
label: "vimeo",
43+
regex: /\[.*\]\((https:\/\/.*vimeo.*)\)/gm,
44+
// we use to have the following, but the above should handle both the player an not-player urls.
45+
//regex: /\[.*\]\((.*player\.vimeo.*)\)/gm, // player.vimeo
46+
47+
imports: [`import ReactPlayer from "react-player";`],
48+
output: `<ReactPlayer controls url="$1" />`,
49+
},
50+
],
51+
};

src/transform.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export async function getMarkdownFromNotionBlocks(
5656
//console.log("markdown after link fixes", markdown);
5757

5858
// simple regex-based tweaks. These are usually related to docusaurus
59-
const { imports, body } = doRegexMarkdownTransforms(config, markdown);
59+
const { imports, body } = doTransformsOnMarkdown(config, markdown);
6060

6161
// console.log("markdown after regex fixes", markdown);
6262
// console.log("body after regex", body);
@@ -81,26 +81,24 @@ function doNotionBlockTransforms(
8181
}
8282
}
8383

84-
// simple regex replacements on the markdown output
85-
function doRegexMarkdownTransforms(config: IDocuNotionConfig, input: string) {
84+
function doTransformsOnMarkdown(config: IDocuNotionConfig, input: string) {
8685
const regexMods: IRegexMarkdownModification[] = config.plugins
8786
.filter(plugin => !!plugin.regexMarkdownModifications)
8887
.map(plugin => plugin.regexMarkdownModifications!)
8988
.flat();
9089

9190
let body = input;
91+
//console.log("body before regex: " + body);
9292
let match;
9393
const imports = new Set<string>();
9494

9595
// eslint-disable-next-line @typescript-eslint/no-unused-vars
9696
regexMods.forEach(mod => {
97+
//verbose(`Trying [${mod.label}]`);
9798
while ((match = mod.regex.exec(input)) !== null) {
9899
const string = match[0];
99100
const url = match[1];
100-
logDebug(
101-
"DocusaurusTweaks",
102-
`${string} --> ${mod.output.replace("$1", url)}`
103-
);
101+
verbose(`[${mod.label}] ${string} --> ${mod.output.replace("$1", url)}`);
104102
body = body.replace(string, mod.output.replace("$1", url));
105103
// add any library imports
106104
mod.imports?.forEach(imp => imports.add(imp));

yarn.lock

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6211,11 +6211,6 @@ please-upgrade-node@^3.2.0:
62116211
dependencies:
62126212
semver-compare "^1.0.0"
62136213

6214-
postinstall-postinstall@^2.1.0:
6215-
version "2.1.0"
6216-
resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3"
6217-
integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ==
6218-
62196214
prelude-ls@^1.2.1:
62206215
version "1.2.1"
62216216
resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz"

0 commit comments

Comments
 (0)