Skip to content

fix: Use video player only for embedded videos (#60) #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions src/config/default.docunotion.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
gifEmbed,
imgurGifEmbed,
vimeoEmbed,
youtubeEmbed,
} from "../plugins/embedTweaks";
import { gifEmbed, imgurGifEmbed } from "../plugins/embedTweaks";
import { standardImageTransformer } from "../images";
import { standardInternalLinkConversion } from "../plugins/internalLinks";
import { standardCalloutTransformer } from "../plugins/CalloutTransformer";
Expand All @@ -13,6 +8,7 @@ import { standardEscapeHtmlBlockModifier } from "../plugins/EscapeHtmlBlockModif
import { standardHeadingTransformer } from "../plugins/HeadingTransformer";
import { standardNumberedListTransformer } from "../plugins/NumberedListTransformer";
import { standardTableTransformer } from "../plugins/TableTransformer";
import { standardVideoTransformer } from "../plugins/VideoTransformer";
import { standardExternalLinkConversion } from "../plugins/externalLinks";
import { IDocuNotionConfig } from "./configuration";

Expand All @@ -30,6 +26,7 @@ const defaultConfig: IDocuNotionConfig = {
standardCalloutTransformer,
standardTableTransformer,
standardNumberedListTransformer,
standardVideoTransformer,

// Link modifiers, which are special because they can read metadata from all the pages in order to figure out the correct url
standardInternalLinkConversion,
Expand All @@ -38,8 +35,6 @@ const defaultConfig: IDocuNotionConfig = {
// Regexps plus javascript `import`s that operate on the Markdown output
imgurGifEmbed,
gifEmbed,
youtubeEmbed,
vimeoEmbed,
],
};

Expand Down
87 changes: 87 additions & 0 deletions src/plugins/VideoTransformer.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { setLogLevel } from "../log";
import { NotionBlock } from "../types";
import { standardVideoTransformer } from "./VideoTransformer";
import { blocksToMarkdown } from "./pluginTestRun";

test("youtube embedded", async () => {
const config = { plugins: [standardVideoTransformer] };
const result = await blocksToMarkdown(config, [
{
object: "block",
type: "video",
video: {
caption: [
{
type: "text",
text: {
content: "A video about editing in Notion",
link: null,
},
plain_text: "A video about editing in Notion",
href: null,
},
],
type: "external",
external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
},
} as unknown as NotionBlock,
]);
expect(result).toContain(`import ReactPlayer from "react-player";`);
expect(result).toContain(
`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`
);
});

test("vimeo embedded", async () => {
setLogLevel("verbose");
const config = { plugins: [standardVideoTransformer] };
const result = await blocksToMarkdown(config, [
{
object: "block",
type: "video",
video: {
caption: [],
type: "external",
external: { url: "https://vimeo.com/4613611xx" },
},
} as unknown as NotionBlock,
]);
expect(result).toContain(`import ReactPlayer from "react-player";`);
expect(result).toContain(
`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`
);
});

test("video link, not embedded", async () => {
setLogLevel("verbose");
const config = { plugins: [standardVideoTransformer] };
const result = await blocksToMarkdown(config, [
{
object: "block",
type: "paragraph",
paragraph: {
rich_text: [
{
type: "text",
text: {
content: "https://vimeo.com/4613611xx",
link: {
url: "https://vimeo.com/4613611xx",
},
},
annotations: {
code: false,
},
plain_text: "https://vimeo.com/4613611xx",
href: "https://vimeo.com/4613611xx",
},
],
color: "default",
},
} as unknown as NotionBlock,
]);
expect(result).toContain(
"[https://vimeo.com/4613611xx](https://vimeo.com/4613611xx)"
);
expect(result).not.toContain(`import`);
});
29 changes: 29 additions & 0 deletions src/plugins/VideoTransformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { VideoBlockObjectResponse } from "@notionhq/client/build/src/api-endpoints";
import { IDocuNotionContext, IPlugin } from "./pluginTypes";
import { warning } from "../log";
import { NotionBlock } from "../types";

export const standardVideoTransformer: IPlugin = {
name: "video",
notionToMarkdownTransforms: [
{
type: "video",
getStringFromBlock: (
context: IDocuNotionContext,
block: NotionBlock
): string => {
const video = (block as VideoBlockObjectResponse).video;
if (video.type === "external") {
if (!context.imports) context.imports = [];
context.imports.push(`import ReactPlayer from "react-player";`);
return `<ReactPlayer controls url="${video.external.url}" />`;
} else {
warning(
`[standardVideoTransformer] Found Notion "video" block with type ${video.type}. The best docu-notion can do for now is ignore it.`
);
}
return "";
},
},
],
};
60 changes: 1 addition & 59 deletions src/plugins/embedTweaks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,7 @@ import { NotionBlock } from "../types";
import { IPlugin } from "./pluginTypes";
import { setLogLevel } from "../log";
import { blocksToMarkdown } from "./pluginTestRun";
import {
gifEmbed,
imgurGifEmbed,
vimeoEmbed,
youtubeEmbed,
} from "./embedTweaks";

test("youtube", async () => {
const config = { plugins: [youtubeEmbed] };
const result = await blocksToMarkdown(config, [
{
object: "block",
id: "e6ddd1d4-36d4-4925-94c1-5dff4662c1f3",
has_children: false,
archived: false,
type: "video",
video: {
caption: [
{
type: "text",
text: {
content: "A video about editing in Notion",
link: null,
},
plain_text: "A video about editing in Notion",
href: null,
},
],
type: "external",
external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
},
} as unknown as NotionBlock,
]);
expect(result).toContain(`import ReactPlayer from "react-player";`);
expect(result).toContain(
`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`
);
});

test("vimeo", async () => {
setLogLevel("verbose");
const config = { plugins: [vimeoEmbed] };
const result = await blocksToMarkdown(config, [
{
object: "block",
id: "39ff83a3-2fb5-4411-a715-960656a177ff",
type: "video",
video: {
caption: [],
type: "external",
external: { url: "https://vimeo.com/4613611xx" },
},
} as unknown as NotionBlock,
]);
expect(result).toContain(`import ReactPlayer from "react-player";`);
expect(result).toContain(
`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`
);
});
import { gifEmbed, imgurGifEmbed } from "./embedTweaks";

test("imgur", async () => {
setLogLevel("verbose");
Expand Down
23 changes: 0 additions & 23 deletions src/plugins/embedTweaks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,3 @@ export const imgurGifEmbed: IPlugin = {
},
],
};
export const youtubeEmbed: IPlugin = {
name: "youtube",
regexMarkdownModifications: [
{
regex: /\[.*\]\((.*youtube\.com\/watch.*)\)/, //youtube.com/watch
imports: [`import ReactPlayer from "react-player";`],
replacementPattern: `<ReactPlayer controls url="$1" />`,
},
],
};
export const vimeoEmbed: IPlugin = {
name: "vimeo",
regexMarkdownModifications: [
{
regex: /\[.*\]\((https:\/\/.*vimeo.*)\)/,
// we use to have the following, but the above should handle both the player an not-player urls.
//regex: /\[.*\]\((.*player\.vimeo.*)\)/gm, // player.vimeo

imports: [`import ReactPlayer from "react-player";`],
replacementPattern: `<ReactPlayer controls url="$1" />`,
},
],
};
19 changes: 17 additions & 2 deletions src/plugins/externalLinks.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { setLogLevel, verbose } from "../log";
import { NotionPage } from "../NotionPage";
import { setLogLevel } from "../log";
import { oneBlockToMarkdown } from "./pluginTestRun";
import { standardExternalLinkConversion } from "./externalLinks";

Expand All @@ -15,6 +14,22 @@ test("links turned into bookmarks", async () => {
expect(results.trim()).toBe("[https://github.com](https://github.com)");
});

test("video links turned into bookmarks", async () => {
setLogLevel("debug");
const results = await getMarkdown({
object: "block",
type: "bookmark",
bookmark: {
caption: [],
url: "https://vimeo.com/4613611xx",
},
});
expect(results).toContain(
"[https://vimeo.com/4613611xx](https://vimeo.com/4613611xx)"
);
expect(results).not.toContain(`import`);
});

test("external link inside callout", async () => {
const results = await getMarkdown({
type: "callout",
Expand Down
9 changes: 8 additions & 1 deletion src/plugins/pluginTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export type IRegexMarkdownModification = {
// normally, anything in code blocks is will be ignored. If you want to make changes inside of code blocks, set this to true.
includeCodeBlocks?: boolean;

// If the output is creating things like react elements, you can import their definitions here
// If the output is creating things like react elements, you can append their import definitions
// to this array so they get added to the page.
// e.g. mod.imports.push(`import ReactPlayer from "react-player";`);
imports?: string[];
};

Expand All @@ -74,4 +76,9 @@ export type IDocuNotionContext = {
convertNotionLinkToLocalDocusaurusLink: (url: string) => string | undefined;
pages: NotionPage[];
counts: ICounts;

// If the output is creating things like react elements, you can append their import definitions
// to this array so they get added to the page.
// e.g. context.imports.push(`import ReactPlayer from "react-player";`);
imports?: string[];
};
17 changes: 8 additions & 9 deletions src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,14 @@ export async function getMarkdownFromNotionBlocks(
//console.log("markdown after link fixes", markdown);

// simple regex-based tweaks. These are usually related to docusaurus
const { imports, body } = await doTransformsOnMarkdown(
context,
config,
markdown
);
const body = await doTransformsOnMarkdown(context, config, markdown);

// console.log("markdown after regex fixes", markdown);
// console.log("body after regex", body);

const uniqueImports = [...new Set(context.imports)];
const imports = uniqueImports.join("\n");
context.imports = []; // reset for next page
return `${imports}\n${body}`;
}

Expand Down Expand Up @@ -106,7 +105,6 @@ async function doTransformsOnMarkdown(
let body = input;
//console.log("body before regex: " + body);
let match;
const imports = new Set<string>();

// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const mod of regexMods) {
Expand Down Expand Up @@ -143,15 +141,16 @@ async function doTransformsOnMarkdown(
body =
precedingPart +
partStartingFromThisMatch.replace(original, replacement);

// add any library imports
mod.imports?.forEach(imp => imports.add(imp));
if (!context.imports) context.imports = [];
context.imports.push(...(mod.imports || []));
}
}
}
}
logDebug("doTransformsOnMarkdown", "body after regex: " + body);
const uniqueImports = [...new Set(imports)];
return { body, imports: [...uniqueImports].join("\n") };
return body;
}

async function doNotionToMarkdown(
Expand Down