notion-to-md 1.0.5 → 1.0.9
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/README.md +32 -11
- package/main.d.ts +18 -0
- package/notion-to-md.js +37 -16
- package/package.json +7 -2
- package/utils/notion.js +29 -5
package/README.md
CHANGED
|
@@ -66,6 +66,8 @@ const n2m = new notion2md({ notionClient: notion });
|
|
|
66
66
|
|
|
67
67
|

|
|
68
68
|
|
|
69
|
+
> **Note:** Details on provided methods can be found in [API section](https://github.com/souvikinator/notion-to-md#api)
|
|
70
|
+
|
|
69
71
|
### converting page to markdown object
|
|
70
72
|
|
|
71
73
|
This is how the notion page looks for this example:
|
|
@@ -84,11 +86,17 @@ const notion = new Client({
|
|
|
84
86
|
const n2m = new notion2md({ notionClient: notion });
|
|
85
87
|
|
|
86
88
|
(async () => {
|
|
87
|
-
|
|
89
|
+
// notice second argument, totalPage.
|
|
90
|
+
const x = await n2m.pageToMarkdown("target_page_id", 2);
|
|
88
91
|
console.log(x);
|
|
89
92
|
})();
|
|
90
93
|
```
|
|
91
94
|
|
|
95
|
+
> `totalPage`: Default value is `1` which means only `100` blocks will be converted to markdown and rest will be ignored (due to notion api limitations, ref: [#9](https://github.com/souvikinator/notion-to-md/pull/9)).
|
|
96
|
+
>
|
|
97
|
+
> - if the notion page contains less than or equal `100` blocks then `totalPage` arg is not required.
|
|
98
|
+
> - if the notion page contains `150` blocks then `totalPage` argument should be greater than or equal to `2` leading to `pageSize = 2 * 100` and rendering all `150` blocks.
|
|
99
|
+
|
|
92
100
|
**Output:**
|
|
93
101
|
|
|
94
102
|
```json
|
|
@@ -167,10 +175,16 @@ const n2m = new notion2md({ notionClient: notion });
|
|
|
167
175
|
|
|
168
176
|
### Converting a single block to markdown string
|
|
169
177
|
|
|
170
|
-
-
|
|
178
|
+
- only takes a single notion block and returns corresponding markdown string
|
|
171
179
|
- nesting is ignored
|
|
180
|
+
- not dependent on @notionhq/client
|
|
172
181
|
|
|
173
182
|
```js
|
|
183
|
+
const notion2md = require("notion-to-md");
|
|
184
|
+
|
|
185
|
+
// notion client not required
|
|
186
|
+
const n2m = new notion2md();
|
|
187
|
+
|
|
174
188
|
const result = n2m.blockToMarkdown(block);
|
|
175
189
|
console.log(result);
|
|
176
190
|
```
|
|
@@ -188,26 +202,33 @@ console.log(result);
|
|
|
188
202
|
- takes output of `pageToMarkdown` or `blocksToMarkdown` as argument
|
|
189
203
|
- convert to markdown string.
|
|
190
204
|
|
|
191
|
-
### `pageToMarkdown(page_id)`
|
|
205
|
+
### `pageToMarkdown(page_id,totalPage)`
|
|
192
206
|
|
|
193
|
-
- Takes page_id as input and converts all the blocks in the page to corresponding markdown
|
|
194
207
|
- Uses `blocksToMarkdown` internally.
|
|
208
|
+
- Takes `page_id` as input and converts all the blocks in the page to corresponding markdown object
|
|
209
|
+
- `totalPage` is the retrieve block children request number i.e `page_size Maximum = totalPage * 100`.
|
|
195
210
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
-
|
|
199
|
-
-
|
|
200
|
-
- This method doesn't require the `notion-sdk-js`.
|
|
201
|
-
- Refer docs to know more about [notion blocks](https://developers.notion.com/reference/block)
|
|
211
|
+
> `totalPage`: Default value is `1` which means only `100` blocks will be converted to markdown and rest will be ignored (due to notion api limitations, ref: [#9](https://github.com/souvikinator/notion-to-md/pull/9)).
|
|
212
|
+
>
|
|
213
|
+
> - if the notion page contains less than or equal `100` blocks then `totalPage` arg is not required.
|
|
214
|
+
> - if the notion page contains `150` blocks then `totalPage` argument should be greater than or equal to `2` leading to `pageSize = 2 * 100` and rendering all blocks withing limit `200`.
|
|
202
215
|
|
|
203
|
-
### `blocksToMarkdown(blocks)`
|
|
216
|
+
### `blocksToMarkdown(blocks,totalPage)`
|
|
204
217
|
|
|
205
218
|
> **Note**: requires <u>**notion-sdk-js**</u> unlike `blockToMarkdown`
|
|
206
219
|
|
|
207
220
|
- `blocks`: array of notion blocks
|
|
221
|
+
- `totalPage`: the retrieve block children request number i.e `page_size Maximum = totalPage * 100`.
|
|
208
222
|
- deals with <u>**nested blocks**</u>
|
|
209
223
|
- uses `blockToMarkdown` internally.
|
|
210
224
|
|
|
225
|
+
### `blockToMarkdown(block)`
|
|
226
|
+
|
|
227
|
+
- Takes single notion block and converts to markdown string
|
|
228
|
+
- does not deal with nested notion blocks
|
|
229
|
+
- This method doesn't require the `notion-sdk-js`.
|
|
230
|
+
- Refer docs to know more about [notion blocks](https://developers.notion.com/reference/block)
|
|
231
|
+
|
|
211
232
|
## Contribution
|
|
212
233
|
|
|
213
234
|
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
package/main.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface MdBlock {
|
|
2
|
+
parent: string;
|
|
3
|
+
children: MdBlock[];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
declare module "notion-to-md" {
|
|
7
|
+
export default class Notion2md {
|
|
8
|
+
constructor({ notionClient }: { notionClient: any });
|
|
9
|
+
pageToMarkdown(page_id: string, totalPage: number = 1): Promise<MdBlock[]>;
|
|
10
|
+
toMarkdownString(mdBlocks: MdBlock[]): string;
|
|
11
|
+
blocksToMarkdown(
|
|
12
|
+
blocks: any,
|
|
13
|
+
mdBlocks: MdBlock[],
|
|
14
|
+
totalPage: number = 1
|
|
15
|
+
): Promise<MdBlock[]>;
|
|
16
|
+
blockToMarkdown(block: any): string;
|
|
17
|
+
}
|
|
18
|
+
}
|
package/notion-to-md.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
const md = require("./utils/md");
|
|
2
2
|
const { getBlockChildren } = require("./utils/notion");
|
|
3
|
-
|
|
4
3
|
class notion2md {
|
|
5
4
|
constructor(options) {
|
|
6
|
-
if (!options
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
if (!options) {
|
|
6
|
+
this.notionClient = undefined;
|
|
7
|
+
} else {
|
|
8
|
+
this.notionClient = options.notionClient || undefined;
|
|
9
|
+
}
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
toMarkdownString(mdBlocks = [], nestingLevel = 0) {
|
|
@@ -25,22 +24,36 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
|
|
|
25
24
|
return mdString;
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
/**
|
|
28
|
+
* @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100
|
|
29
|
+
*/
|
|
30
|
+
async pageToMarkdown(id, totalPage = 1) {
|
|
29
31
|
if (!id) throw new Error("pageToMarkdown takes page_id as argument");
|
|
30
|
-
const blocks = await getBlockChildren(this.notionClient, id);
|
|
32
|
+
const blocks = await getBlockChildren(this.notionClient, id, totalPage);
|
|
31
33
|
const parsedData = await this.blocksToMarkdown(blocks);
|
|
32
34
|
return parsedData;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
36
38
|
* @param {object} blocks - list of notion blocks
|
|
39
|
+
* @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100
|
|
37
40
|
* @returns array of md blocks with their children
|
|
38
41
|
*/
|
|
39
|
-
async blocksToMarkdown(blocks, mdBlocks = []) {
|
|
42
|
+
async blocksToMarkdown(blocks, mdBlocks = [], totalPage = 1) {
|
|
43
|
+
if (!this.notionClient) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md"
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
40
49
|
for (let i = 0; i < blocks.length; i++) {
|
|
41
50
|
let block = blocks[i];
|
|
42
51
|
if (block.has_children) {
|
|
43
|
-
let child_blocks = await getBlockChildren(
|
|
52
|
+
let child_blocks = await getBlockChildren(
|
|
53
|
+
this.notionClient,
|
|
54
|
+
block.id,
|
|
55
|
+
totalPage
|
|
56
|
+
);
|
|
44
57
|
mdBlocks.push({ parent: this.blockToMarkdown(block), children: [] });
|
|
45
58
|
let l = mdBlocks.length;
|
|
46
59
|
await this.blocksToMarkdown(child_blocks, mdBlocks[l - 1].children);
|
|
@@ -58,6 +71,8 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
|
|
|
58
71
|
* @returns markdown form of the passed block
|
|
59
72
|
*/
|
|
60
73
|
blockToMarkdown(block) {
|
|
74
|
+
if (!block) throw new Error("notion block required");
|
|
75
|
+
|
|
61
76
|
let parsedData = "",
|
|
62
77
|
blockContent;
|
|
63
78
|
const { type } = block;
|
|
@@ -117,13 +132,19 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
|
|
|
117
132
|
* @param {object} annotations annotation object of a notion block
|
|
118
133
|
*/
|
|
119
134
|
annotatePlainText(text, annotations) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
if (
|
|
135
|
+
const leading_space = text.match(/^\s*/)[0];
|
|
136
|
+
const trailing_space = text.match(/\s*$/)[0];
|
|
137
|
+
text = text.trim();
|
|
138
|
+
|
|
139
|
+
if (text !== "") {
|
|
140
|
+
if (annotations.code) text = md.inlineCode(text);
|
|
141
|
+
if (annotations.bold) text = md.bold(text);
|
|
142
|
+
if (annotations.italic) text = md.italic(text);
|
|
143
|
+
if (annotations.strikethrough) text = md.strikethrough(text);
|
|
144
|
+
if (annotations.underline) text = md.underline(text);
|
|
145
|
+
}
|
|
125
146
|
|
|
126
|
-
return text;
|
|
147
|
+
return leading_space + text + trailing_space;
|
|
127
148
|
}
|
|
128
149
|
}
|
|
129
150
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "notion-to-md",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"main": "notion-to-md.js",
|
|
5
|
+
"typings": "main.d.ts",
|
|
5
6
|
"scripts": {
|
|
6
7
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
8
|
},
|
|
@@ -24,5 +25,9 @@
|
|
|
24
25
|
"url": "https://github.com/souvikinator/notion-to-md/issues"
|
|
25
26
|
},
|
|
26
27
|
"homepage": "https://github.com/souvikinator/notion-to-md#readme",
|
|
27
|
-
"description": "convert notion pages, block and list of blocks to markdown (supports nesting)"
|
|
28
|
+
"description": "convert notion pages, block and list of blocks to markdown (supports nesting)",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@notionhq/client": "^0.4.11",
|
|
31
|
+
"notion-to-md": "^1.0.8"
|
|
32
|
+
}
|
|
28
33
|
}
|
package/utils/notion.js
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
-
exports.getBlockChildren = async (notionClient, block_id) => {
|
|
1
|
+
exports.getBlockChildren = async (notionClient, block_id, totalPage) => {
|
|
2
2
|
try {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
if (!notionClient) {
|
|
4
|
+
throw new Error(
|
|
5
|
+
"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md"
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
let result = [];
|
|
9
|
+
let start_cursor;
|
|
10
|
+
let pageSize = 100;
|
|
11
|
+
for (i = 0; i < totalPage; i++) {
|
|
12
|
+
// contain start_cursor
|
|
13
|
+
const response = await notionClient.blocks.children.list({
|
|
14
|
+
start_cursor: start_cursor,
|
|
15
|
+
page_size: pageSize,
|
|
16
|
+
block_id: block_id,
|
|
17
|
+
});
|
|
18
|
+
let current = response.results;
|
|
19
|
+
// delete start_cursor
|
|
20
|
+
if (start_cursor) {
|
|
21
|
+
current.shift();
|
|
22
|
+
}
|
|
23
|
+
result.push(...current);
|
|
24
|
+
if (current.length < 100) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
pageSize = 101;
|
|
28
|
+
start_cursor = current[current.length - 1].id;
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
7
31
|
} catch (e) {
|
|
8
32
|
console.log(e);
|
|
9
33
|
}
|