@sillsdev/docu-notion 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +135 -0
- package/dist/FlatGuidLayoutStrategy.d.ts +6 -0
- package/dist/FlatGuidLayoutStrategy.js +25 -0
- package/dist/HierarchicalNamedLayoutStrategy.d.ts +7 -0
- package/dist/HierarchicalNamedLayoutStrategy.js +80 -0
- package/dist/LayoutStrategy.d.ts +12 -0
- package/dist/LayoutStrategy.js +83 -0
- package/dist/MakeImagePersistencePlan.d.ts +2 -0
- package/dist/MakeImagePersistencePlan.js +66 -0
- package/dist/NotionImage-CaptionReading.spec.d.ts +1 -0
- package/dist/NotionImage-CaptionReading.spec.js +233 -0
- package/dist/NotionPage.d.ts +45 -0
- package/dist/NotionPage.js +229 -0
- package/dist/NotionPage.spec.d.ts +1 -0
- package/dist/NotionPage.spec.js +143 -0
- package/dist/config/configuration.d.ts +5 -0
- package/dist/config/configuration.js +86 -0
- package/dist/config/default.docunotion.config.d.ts +3 -0
- package/dist/config/default.docunotion.config.js +37 -0
- package/dist/images.d.ts +24 -0
- package/dist/images.js +230 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +37 -0
- package/dist/log.d.ts +11 -0
- package/dist/log.js +61 -0
- package/dist/makeImagePersistencePlan.spec.d.ts +1 -0
- package/dist/makeImagePersistencePlan.spec.js +35 -0
- package/dist/notion-styles.css +58 -0
- package/dist/plugins/CalloutTransformer.d.ts +24 -0
- package/dist/plugins/CalloutTransformer.js +88 -0
- package/dist/plugins/CalloutTransformer.spec.d.ts +1 -0
- package/dist/plugins/CalloutTransformer.spec.js +199 -0
- package/dist/plugins/ColumnListTransformer.d.ts +2 -0
- package/dist/plugins/ColumnListTransformer.js +34 -0
- package/dist/plugins/ColumnTransformer.d.ts +2 -0
- package/dist/plugins/ColumnTransformer.js +67 -0
- package/dist/plugins/EscapeHtmlBlockModifier.d.ts +2 -0
- package/dist/plugins/EscapeHtmlBlockModifier.js +41 -0
- package/dist/plugins/EscapeHtmlBlockModifier.spec.d.ts +1 -0
- package/dist/plugins/EscapeHtmlBlockModifier.spec.js +130 -0
- package/dist/plugins/HeadingTranformer.spec.d.ts +1 -0
- package/dist/plugins/HeadingTranformer.spec.js +46 -0
- package/dist/plugins/HeadingTransformer.d.ts +2 -0
- package/dist/plugins/HeadingTransformer.js +63 -0
- package/dist/plugins/NumberedListTransformer.d.ts +2 -0
- package/dist/plugins/NumberedListTransformer.js +55 -0
- package/dist/plugins/NumberedListTransformer.spec.d.ts +1 -0
- package/dist/plugins/NumberedListTransformer.spec.js +86 -0
- package/dist/plugins/TableTransformer.d.ts +5 -0
- package/dist/plugins/TableTransformer.js +70 -0
- package/dist/plugins/embedTweaks.d.ts +5 -0
- package/dist/plugins/embedTweaks.js +46 -0
- package/dist/plugins/embedTweaks.spec.d.ts +1 -0
- package/dist/plugins/embedTweaks.spec.js +230 -0
- package/dist/plugins/externalLinks.d.ts +2 -0
- package/dist/plugins/externalLinks.js +26 -0
- package/dist/plugins/externalLinks.spec.d.ts +1 -0
- package/dist/plugins/externalLinks.spec.js +132 -0
- package/dist/plugins/internalLinks.d.ts +7 -0
- package/dist/plugins/internalLinks.js +102 -0
- package/dist/plugins/internalLinks.spec.d.ts +1 -0
- package/dist/plugins/internalLinks.spec.js +505 -0
- package/dist/plugins/mermaidLinkPlugin.spec.d.ts +1 -0
- package/dist/plugins/mermaidLinkPlugin.spec.js +77 -0
- package/dist/plugins/pluginTestRun.d.ts +10 -0
- package/dist/plugins/pluginTestRun.js +252 -0
- package/dist/plugins/pluginTypes.d.ts +44 -0
- package/dist/plugins/pluginTypes.js +2 -0
- package/dist/pull.d.ts +12 -0
- package/dist/pull.js +255 -0
- package/dist/run.d.ts +1 -0
- package/dist/run.js +35 -0
- package/dist/transform.d.ts +6 -0
- package/dist/transform.js +200 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.js +2 -0
- package/package.json +103 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.standardHeadingTransformer = void 0;
|
|
13
|
+
const log_1 = require("../log");
|
|
14
|
+
// Makes links to headings work in docusaurus
|
|
15
|
+
// https://github.com/sillsdev/docu-notion/issues/20
|
|
16
|
+
function headingTransformer(notionToMarkdown, block) {
|
|
17
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18
|
+
// First, remove the prefix we added to the heading type
|
|
19
|
+
block.type = block.type.replace("DN_", "");
|
|
20
|
+
const markdown = yield notionToMarkdown.blockToMarkdown(block);
|
|
21
|
+
(0, log_1.logDebug)("headingTransformer, markdown of a heading before adding id", markdown);
|
|
22
|
+
// To make heading links work in docusaurus, we append an id. E.g.
|
|
23
|
+
// ### Hello World {#my-explicit-id}
|
|
24
|
+
// See https://docusaurus.io/docs/markdown-features/toc#heading-ids.
|
|
25
|
+
// For some reason, inline links come in without the dashes, so we have to strip
|
|
26
|
+
// dashes here to match them.
|
|
27
|
+
//console.log("block.id", block.id)
|
|
28
|
+
const blockIdWithoutDashes = block.id.replaceAll("-", "");
|
|
29
|
+
// Finally, append the block id so that it can be the target of a link.
|
|
30
|
+
return `${markdown} {#${blockIdWithoutDashes}}`;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.standardHeadingTransformer = {
|
|
34
|
+
name: "standardHeadingTransformer",
|
|
35
|
+
// AP wrote: We have to do this because if
|
|
36
|
+
// we simply set a custom transformer to heading_n, it will keep
|
|
37
|
+
// recursively calling this code, with blockToMarkdown using the custom transformer
|
|
38
|
+
// over and over. Instead, we want blockToMarkdown to give us the normal
|
|
39
|
+
// result, to which we will append the block ID to enable heading links.
|
|
40
|
+
notionBlockModifications: [
|
|
41
|
+
{
|
|
42
|
+
modify: (block) => {
|
|
43
|
+
// "as any" needed because we're putting a value in that is not allowed by the real type
|
|
44
|
+
block.type = block.type.replace("heading", "DN_heading");
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
// then when it comes time to do markdown conversions, we'll get called for each of these
|
|
49
|
+
notionToMarkdownTransforms: [
|
|
50
|
+
{
|
|
51
|
+
type: "DN_heading_1",
|
|
52
|
+
getStringFromBlock: (context, block) => headingTransformer(context.notionToMarkdown, block),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "DN_heading_2",
|
|
56
|
+
getStringFromBlock: (context, block) => headingTransformer(context.notionToMarkdown, block),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: "DN_heading_3",
|
|
60
|
+
getStringFromBlock: (context, block) => headingTransformer(context.notionToMarkdown, block),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.standardNumberedListTransformer = void 0;
|
|
4
|
+
// This is mostly what notion-to-markdown would normally do with a block of type
|
|
5
|
+
// numbered_list_item. A patch is documented at the end.
|
|
6
|
+
function numberedListTransformer(notionToMarkdown, block) {
|
|
7
|
+
var _a, _b, _c;
|
|
8
|
+
//console.log("got numbered list block " + JSON.stringify(block));
|
|
9
|
+
// In this case typescript is not able to index the types properly, hence ignoring the error
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
const blockContent =
|
|
12
|
+
// @ts-ignore
|
|
13
|
+
((_a = block.numbered_list_item) === null || _a === void 0 ? void 0 : _a.text) || ((_b = block.numbered_list_item) === null || _b === void 0 ? void 0 : _b.rich_text) || [];
|
|
14
|
+
let parsedData = "";
|
|
15
|
+
blockContent.map((content) => {
|
|
16
|
+
const annotations = content.annotations;
|
|
17
|
+
let plain_text = content.plain_text;
|
|
18
|
+
plain_text = notionToMarkdown.annotatePlainText(plain_text, annotations);
|
|
19
|
+
if (content["href"]) {
|
|
20
|
+
plain_text = `[${plain_text}](${content["href"]})`;
|
|
21
|
+
}
|
|
22
|
+
parsedData += plain_text;
|
|
23
|
+
});
|
|
24
|
+
// There is code in notion-to-md which attempts to set an incrementing number
|
|
25
|
+
// on each of these. Somehow it fails; in my testing, block.numbered_list_item never
|
|
26
|
+
// has a field 'number'. But we don't actually need incrementing numbers;
|
|
27
|
+
// markdown will do the numbering if we just make something that looks like
|
|
28
|
+
// a member of a numbered list by starting with number followed by period and space.
|
|
29
|
+
// I'm keeping the original code in case notion-to-md gets fixed and there is actually
|
|
30
|
+
// some reason to use incrementing numbers (it would at least make the markdown more
|
|
31
|
+
// human-readable); but this at least works.
|
|
32
|
+
// A problem is that in notion, a numbered list may continue after some intermediate
|
|
33
|
+
// content. To achieve this in markdown, we'd need to indent the intermediate content
|
|
34
|
+
// by a tab. Not only is it difficult to do this, but there appears to be no way to
|
|
35
|
+
// know whether we should. The data we get from notion doesn't include the item number,
|
|
36
|
+
// and its parent is the page rather than a particular list. So there is no way I can
|
|
37
|
+
// see to distinguish a list continuation from a new list. The code here will leave
|
|
38
|
+
// it up to markdown to decide whether to start a new list; I believe it will do so
|
|
39
|
+
// if it sees any intervening lines that are not list items.
|
|
40
|
+
let num = (_c = block.numbered_list_item) === null || _c === void 0 ? void 0 : _c.number;
|
|
41
|
+
//console.log("got number " + num?.toString());
|
|
42
|
+
if (!num) {
|
|
43
|
+
num = 1;
|
|
44
|
+
}
|
|
45
|
+
return Promise.resolve(`${num}. ${parsedData.trim()}`);
|
|
46
|
+
}
|
|
47
|
+
exports.standardNumberedListTransformer = {
|
|
48
|
+
name: "standardNumberedListTransformer",
|
|
49
|
+
notionToMarkdownTransforms: [
|
|
50
|
+
{
|
|
51
|
+
type: "numbered_list_item",
|
|
52
|
+
getStringFromBlock: (context, block) => numberedListTransformer(context.notionToMarkdown, block),
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const pluginTestRun_1 = require("./pluginTestRun");
|
|
13
|
+
const NumberedListTransformer_1 = require("./NumberedListTransformer");
|
|
14
|
+
let block;
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
block = {
|
|
17
|
+
has_children: false,
|
|
18
|
+
archived: false,
|
|
19
|
+
type: "callout",
|
|
20
|
+
callout: {
|
|
21
|
+
rich_text: [
|
|
22
|
+
{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: { content: "This is information callout", link: null },
|
|
25
|
+
annotations: {
|
|
26
|
+
bold: false,
|
|
27
|
+
italic: false,
|
|
28
|
+
strikethrough: false,
|
|
29
|
+
underline: false,
|
|
30
|
+
code: false,
|
|
31
|
+
color: "default",
|
|
32
|
+
},
|
|
33
|
+
plain_text: "This is the callout",
|
|
34
|
+
href: null,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
icon: { type: "emoji", emoji: "ℹ️" },
|
|
38
|
+
color: "gray_background",
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
test("external link inside numbered list, italic preserved", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const config = { plugins: [NumberedListTransformer_1.standardNumberedListTransformer] };
|
|
44
|
+
const results = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
45
|
+
{
|
|
46
|
+
type: "numbered_list_item",
|
|
47
|
+
numbered_list_item: {
|
|
48
|
+
rich_text: [
|
|
49
|
+
{
|
|
50
|
+
type: "text",
|
|
51
|
+
text: { content: "link ", link: null },
|
|
52
|
+
annotations: {
|
|
53
|
+
bold: false,
|
|
54
|
+
italic: false,
|
|
55
|
+
strikethrough: false,
|
|
56
|
+
underline: false,
|
|
57
|
+
code: false,
|
|
58
|
+
color: "default",
|
|
59
|
+
},
|
|
60
|
+
plain_text: "link ",
|
|
61
|
+
href: null,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: "text",
|
|
65
|
+
text: {
|
|
66
|
+
content: "github",
|
|
67
|
+
link: { url: "https://github.com" },
|
|
68
|
+
},
|
|
69
|
+
annotations: {
|
|
70
|
+
bold: false,
|
|
71
|
+
italic: true,
|
|
72
|
+
strikethrough: false,
|
|
73
|
+
underline: false,
|
|
74
|
+
code: false,
|
|
75
|
+
color: "default",
|
|
76
|
+
},
|
|
77
|
+
plain_text: "github",
|
|
78
|
+
href: "https://github.com",
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
color: "default",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
expect(results.trim()).toBe(`1. link [_github_](https://github.com)`);
|
|
86
|
+
}));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NotionToMarkdown } from "notion-to-md";
|
|
2
|
+
import { IGetBlockChildrenFn, IPlugin } from "./pluginTypes";
|
|
3
|
+
import { NotionBlock } from "../types";
|
|
4
|
+
export declare function tableTransformer(notionToMarkdown: NotionToMarkdown, getBlockChildren: IGetBlockChildrenFn, block: NotionBlock): Promise<string>;
|
|
5
|
+
export declare const standardTableTransformer: IPlugin;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.standardTableTransformer = exports.tableTransformer = void 0;
|
|
16
|
+
const markdown_table_1 = __importDefault(require("markdown-table"));
|
|
17
|
+
// This is mostly a copy of the table handler from notion-to-md. The change is to handle newlines in the
|
|
18
|
+
// notion cell content.
|
|
19
|
+
function tableTransformer(notionToMarkdown, getBlockChildren, block) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
const { id, has_children } = block;
|
|
22
|
+
const tableArr = [];
|
|
23
|
+
if (has_children) {
|
|
24
|
+
const tableRows = yield getBlockChildren(id);
|
|
25
|
+
// console.log(">>", tableRows);
|
|
26
|
+
const rowsPromise = tableRows === null || tableRows === void 0 ? void 0 : tableRows.map((row) => __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
const { type } = row;
|
|
28
|
+
const cells = row[type]["cells"];
|
|
29
|
+
/**
|
|
30
|
+
* this is more like a hack since matching the type text was
|
|
31
|
+
* difficult. So converting each cell to paragraph type to
|
|
32
|
+
* reuse the blockToMarkdown function
|
|
33
|
+
*/
|
|
34
|
+
const cellStringPromise = cells.map((cell) => __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
return yield notionToMarkdown.blockToMarkdown({
|
|
36
|
+
type: "paragraph",
|
|
37
|
+
paragraph: { rich_text: cell },
|
|
38
|
+
});
|
|
39
|
+
}));
|
|
40
|
+
const cellStringArrRaw = yield Promise.all(cellStringPromise);
|
|
41
|
+
// This is our patch to the original notion-to-md code.
|
|
42
|
+
const cellStringArr = cellStringArrRaw.map(c => c
|
|
43
|
+
// Trailing newlines are almost certainly not wanted, and converting to br's gives weird results
|
|
44
|
+
.replace(/[\r\n]+$/, "")
|
|
45
|
+
// Preserving line breaks within cells can't be done in stock markdown. Since we're producing
|
|
46
|
+
// mdx, which supports embedded HTML, we can handle it with <br/>.
|
|
47
|
+
// I'm not sure exactly what line breaks might occur in the input, depending on platform,
|
|
48
|
+
// so handle all the common cases.
|
|
49
|
+
.replaceAll("\r\n", "<br/>")
|
|
50
|
+
.replaceAll("\n", "<br/>")
|
|
51
|
+
.replaceAll("\r", "<br/>"));
|
|
52
|
+
// console.log("~~", cellStringArr);
|
|
53
|
+
tableArr.push(cellStringArr);
|
|
54
|
+
// console.log(tableArr);
|
|
55
|
+
}));
|
|
56
|
+
yield Promise.all(rowsPromise || []);
|
|
57
|
+
}
|
|
58
|
+
return (0, markdown_table_1.default)(tableArr);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
exports.tableTransformer = tableTransformer;
|
|
62
|
+
exports.standardTableTransformer = {
|
|
63
|
+
name: "standardTableTransformer",
|
|
64
|
+
notionToMarkdownTransforms: [
|
|
65
|
+
{
|
|
66
|
+
type: "table",
|
|
67
|
+
getStringFromBlock: (context, block) => tableTransformer(context.notionToMarkdown, context.getBlockChildren, block),
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vimeoEmbed = exports.youtubeEmbed = exports.imgurGifEmbed = exports.gifEmbed = void 0;
|
|
4
|
+
exports.gifEmbed = {
|
|
5
|
+
name: "gif",
|
|
6
|
+
regexMarkdownModifications: [
|
|
7
|
+
{
|
|
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)))\)/,
|
|
11
|
+
replacementPattern: ``,
|
|
12
|
+
},
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
exports.imgurGifEmbed = {
|
|
16
|
+
name: "imgur",
|
|
17
|
+
regexMarkdownModifications: [
|
|
18
|
+
{
|
|
19
|
+
regex: /\[.*\]\((.*imgur\.com\/.*)\)/,
|
|
20
|
+
// imgur links to gifs need a .gif at the end, but the url they give you doesn't have one.
|
|
21
|
+
replacementPattern: ``,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
exports.youtubeEmbed = {
|
|
26
|
+
name: "youtube",
|
|
27
|
+
regexMarkdownModifications: [
|
|
28
|
+
{
|
|
29
|
+
regex: /\[.*\]\((.*youtube\.com\/watch.*)\)/,
|
|
30
|
+
imports: [`import ReactPlayer from "react-player";`],
|
|
31
|
+
replacementPattern: `<ReactPlayer controls url="$1" />`,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
exports.vimeoEmbed = {
|
|
36
|
+
name: "vimeo",
|
|
37
|
+
regexMarkdownModifications: [
|
|
38
|
+
{
|
|
39
|
+
regex: /\[.*\]\((https:\/\/.*vimeo.*)\)/,
|
|
40
|
+
// we use to have the following, but the above should handle both the player an not-player urls.
|
|
41
|
+
//regex: /\[.*\]\((.*player\.vimeo.*)\)/gm, // player.vimeo
|
|
42
|
+
imports: [`import ReactPlayer from "react-player";`],
|
|
43
|
+
replacementPattern: `<ReactPlayer controls url="$1" />`,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const log_1 = require("../log");
|
|
13
|
+
const pluginTestRun_1 = require("./pluginTestRun");
|
|
14
|
+
const embedTweaks_1 = require("./embedTweaks");
|
|
15
|
+
test("youtube", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
const config = { plugins: [embedTweaks_1.youtubeEmbed] };
|
|
17
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
18
|
+
{
|
|
19
|
+
object: "block",
|
|
20
|
+
id: "e6ddd1d4-36d4-4925-94c1-5dff4662c1f3",
|
|
21
|
+
has_children: false,
|
|
22
|
+
archived: false,
|
|
23
|
+
type: "video",
|
|
24
|
+
video: {
|
|
25
|
+
caption: [
|
|
26
|
+
{
|
|
27
|
+
type: "text",
|
|
28
|
+
text: {
|
|
29
|
+
content: "A video about editing in Notion",
|
|
30
|
+
link: null,
|
|
31
|
+
},
|
|
32
|
+
plain_text: "A video about editing in Notion",
|
|
33
|
+
href: null,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
type: "external",
|
|
37
|
+
external: { url: "https://www.youtube.com/watch?v=FXIrojSK3Jo" },
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
]);
|
|
41
|
+
expect(result).toContain(`import ReactPlayer from "react-player";`);
|
|
42
|
+
expect(result).toContain(`<ReactPlayer controls url="https://www.youtube.com/watch?v=FXIrojSK3Jo" />`);
|
|
43
|
+
}));
|
|
44
|
+
test("vimeo", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
+
(0, log_1.setLogLevel)("verbose");
|
|
46
|
+
const config = { plugins: [embedTweaks_1.vimeoEmbed] };
|
|
47
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
48
|
+
{
|
|
49
|
+
object: "block",
|
|
50
|
+
id: "39ff83a3-2fb5-4411-a715-960656a177ff",
|
|
51
|
+
type: "video",
|
|
52
|
+
video: {
|
|
53
|
+
caption: [],
|
|
54
|
+
type: "external",
|
|
55
|
+
external: { url: "https://vimeo.com/4613611xx" },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
expect(result).toContain(`import ReactPlayer from "react-player";`);
|
|
60
|
+
expect(result).toContain(`<ReactPlayer controls url="https://vimeo.com/4613611xx" />`);
|
|
61
|
+
}));
|
|
62
|
+
test("imgur", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
(0, log_1.setLogLevel)("verbose");
|
|
64
|
+
const config = { plugins: [embedTweaks_1.imgurGifEmbed] };
|
|
65
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
66
|
+
{
|
|
67
|
+
object: "block",
|
|
68
|
+
id: "e36710d8-98ad-40dc-b41b-b376ebdd6894",
|
|
69
|
+
type: "bookmark",
|
|
70
|
+
bookmark: { caption: [], url: "https://imgur.com/gallery/U8TTNuI" },
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
expect(result.trim()).toBe(``);
|
|
74
|
+
}));
|
|
75
|
+
test("gif", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
+
(0, log_1.setLogLevel)("verbose");
|
|
77
|
+
const config = { plugins: [embedTweaks_1.gifEmbed] };
|
|
78
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
79
|
+
{
|
|
80
|
+
object: "block",
|
|
81
|
+
id: "e36710d8-98ad-40dc-b41b-b376ebdd6894",
|
|
82
|
+
type: "bookmark",
|
|
83
|
+
bookmark: {
|
|
84
|
+
caption: [],
|
|
85
|
+
url: "https://en.wikipedia.org/wiki/GIF#/media/File:Rotating_earth_(large).gif",
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
expect(result.trim()).toBe(`.gif)`);
|
|
90
|
+
}));
|
|
91
|
+
test("tweaks are not applied inside code blocks", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
(0, log_1.setLogLevel)("verbose");
|
|
93
|
+
const p = {
|
|
94
|
+
name: "test",
|
|
95
|
+
regexMarkdownModifications: [
|
|
96
|
+
{
|
|
97
|
+
regex: /find/,
|
|
98
|
+
replacementPattern: `found`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
const config = { plugins: [p] };
|
|
103
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
104
|
+
{
|
|
105
|
+
type: "code",
|
|
106
|
+
code: {
|
|
107
|
+
caption: [],
|
|
108
|
+
rich_text: [
|
|
109
|
+
{
|
|
110
|
+
type: "text",
|
|
111
|
+
text: {
|
|
112
|
+
content: "don't find me",
|
|
113
|
+
link: null,
|
|
114
|
+
},
|
|
115
|
+
annotations: {
|
|
116
|
+
bold: false,
|
|
117
|
+
italic: false,
|
|
118
|
+
strikethrough: false,
|
|
119
|
+
underline: false,
|
|
120
|
+
code: false,
|
|
121
|
+
color: "default",
|
|
122
|
+
},
|
|
123
|
+
plain_text: "don't find me",
|
|
124
|
+
href: null,
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
language: "",
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: "paragraph",
|
|
132
|
+
paragraph: {
|
|
133
|
+
rich_text: [
|
|
134
|
+
{
|
|
135
|
+
type: "text",
|
|
136
|
+
text: { content: "find this", link: null },
|
|
137
|
+
annotations: {
|
|
138
|
+
bold: false,
|
|
139
|
+
italic: false,
|
|
140
|
+
strikethrough: false,
|
|
141
|
+
underline: false,
|
|
142
|
+
code: true,
|
|
143
|
+
color: "default",
|
|
144
|
+
},
|
|
145
|
+
plain_text: "find this",
|
|
146
|
+
href: null,
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
]);
|
|
152
|
+
// we should not change the code one
|
|
153
|
+
expect(result.trim()).toContain("don't find me");
|
|
154
|
+
// but we should change the non-code block one
|
|
155
|
+
expect(result.trim()).toContain("found this");
|
|
156
|
+
}));
|
|
157
|
+
test("simplest possible", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
158
|
+
(0, log_1.setLogLevel)("verbose");
|
|
159
|
+
const p = {
|
|
160
|
+
name: "test",
|
|
161
|
+
regexMarkdownModifications: [
|
|
162
|
+
{
|
|
163
|
+
regex: /find/,
|
|
164
|
+
replacementPattern: `found`,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
const config = { plugins: [p] };
|
|
169
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
170
|
+
{
|
|
171
|
+
type: "paragraph",
|
|
172
|
+
paragraph: {
|
|
173
|
+
rich_text: [
|
|
174
|
+
{
|
|
175
|
+
type: "text",
|
|
176
|
+
text: { content: "find this", link: null },
|
|
177
|
+
annotations: {
|
|
178
|
+
bold: false,
|
|
179
|
+
italic: false,
|
|
180
|
+
strikethrough: false,
|
|
181
|
+
underline: false,
|
|
182
|
+
code: true,
|
|
183
|
+
color: "default",
|
|
184
|
+
},
|
|
185
|
+
plain_text: "find this",
|
|
186
|
+
href: null,
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
]);
|
|
192
|
+
expect(result.trim()).toContain("found this");
|
|
193
|
+
}));
|
|
194
|
+
test("use match in output", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
195
|
+
(0, log_1.setLogLevel)("verbose");
|
|
196
|
+
const p = {
|
|
197
|
+
name: "test",
|
|
198
|
+
regexMarkdownModifications: [
|
|
199
|
+
{
|
|
200
|
+
regex: /(find)/,
|
|
201
|
+
replacementPattern: `found $1`,
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
};
|
|
205
|
+
const config = { plugins: [p] };
|
|
206
|
+
const result = yield (0, pluginTestRun_1.blocksToMarkdown)(config, [
|
|
207
|
+
{
|
|
208
|
+
type: "paragraph",
|
|
209
|
+
paragraph: {
|
|
210
|
+
rich_text: [
|
|
211
|
+
{
|
|
212
|
+
type: "text",
|
|
213
|
+
text: { content: "find this", link: null },
|
|
214
|
+
annotations: {
|
|
215
|
+
bold: false,
|
|
216
|
+
italic: false,
|
|
217
|
+
strikethrough: false,
|
|
218
|
+
underline: false,
|
|
219
|
+
code: true,
|
|
220
|
+
color: "default",
|
|
221
|
+
},
|
|
222
|
+
plain_text: "find this",
|
|
223
|
+
href: null,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
]);
|
|
229
|
+
expect(result.trim()).toContain("found find");
|
|
230
|
+
}));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.standardExternalLinkConversion = void 0;
|
|
4
|
+
const log_1 = require("../log");
|
|
5
|
+
exports.standardExternalLinkConversion = {
|
|
6
|
+
name: "standard external link conversion",
|
|
7
|
+
linkModifier: {
|
|
8
|
+
match: /\[.*\]\(http.*\)/,
|
|
9
|
+
convert: (context, markdownLink) => {
|
|
10
|
+
const linkRegExp = /\[([^\]]+)?\]\((http.*)\)/;
|
|
11
|
+
const match = linkRegExp.exec(markdownLink);
|
|
12
|
+
if (match === null) {
|
|
13
|
+
(0, log_1.error)(`[standardExternalLinkConversion] Could not parse link ${markdownLink}`);
|
|
14
|
+
return markdownLink;
|
|
15
|
+
}
|
|
16
|
+
const label = match[1];
|
|
17
|
+
const url = match[2];
|
|
18
|
+
if (label === "bookmark") {
|
|
19
|
+
const replacement = `[${url}](${url})`;
|
|
20
|
+
(0, log_1.warning)(`[standardExternalLinkConversion] Found Notion "Bookmark" link. In Notion this would show as an embed. The best docu-notion can do at the moment is replace "Bookmark" with the actual URL: ${replacement}`);
|
|
21
|
+
return replacement;
|
|
22
|
+
}
|
|
23
|
+
return `[${label}](${url})`;
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|