notion-to-md 2.1.0 → 2.3.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/README.md CHANGED
@@ -1,11 +1,15 @@
1
1
  <img src="https://imgur.com/WgXdz9r.png" />
2
2
 
3
+ > 💡 For better readability and detailed instructions headover to the [wiki](https://github.com/souvikinator/notion-to-md/wiki)
4
+
3
5
  # Notion to Markdown
4
6
 
5
7
  Convert notion pages, block and list of blocks to markdown (supports nesting) using **[notion-sdk-js](https://github.com/makenotion/notion-sdk-js)**
6
8
 
7
9
  > **Note:** Before getting started, create [an integration and find the token](https://www.notion.so/my-integrations).
8
10
 
11
+ [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/O5O1AFCJR)
12
+
9
13
  ## Todo
10
14
 
11
15
  - [x] heading
@@ -20,7 +24,7 @@ Convert notion pages, block and list of blocks to markdown (supports nesting) us
20
24
  - [x] nested blocks
21
25
  - [ ] pages inside pages/child page
22
26
  - [x] embeds, bookmarks, videos, files (converted to links)
23
- - [ ] tables
27
+ - [x] Simple tables
24
28
  - [x] divider
25
29
  - [x] equation block (converted to code blocks)
26
30
  - [x] convert returned markdown object to string (`toMarkdownString()`)
@@ -46,6 +50,8 @@ This is how the notion page looks for this example:
46
50
  ```js
47
51
  const { Client } = require("@notionhq/client");
48
52
  const { NotionToMarkdown } = require("notion-to-md");
53
+ // or
54
+ // import {NotionToMarkdown} from "notion-to-md";
49
55
 
50
56
  const notion = new Client({
51
57
  auth: "your integration token",
@@ -144,14 +150,14 @@ same notion page as before
144
150
 
145
151
  ```js
146
152
  const { Client } = require("@notionhq/client");
147
- const notion2md = require("notion-to-md");
153
+ const { NotionToMarkdown } = require("notion-to-md");
148
154
 
149
155
  const notion = new Client({
150
156
  auth: "your integration token",
151
157
  });
152
158
 
153
159
  // passing notion client to the option
154
- const n2m = new notion2md({ notionClient: notion });
160
+ const n2m = new NotionToMarkdown({ notionClient: notion });
155
161
 
156
162
  (async () => {
157
163
  // get all blocks in the page
@@ -171,13 +177,13 @@ const n2m = new notion2md({ notionClient: notion });
171
177
 
172
178
  - only takes a single notion block and returns corresponding markdown string
173
179
  - nesting is ignored
174
- - independent of @notionhq/client
180
+ - depends on @notionhq/client
175
181
 
176
182
  ```js
177
- const notion2md = require("notion-to-md");
183
+ const { NotionToMarkdown } = require("notion-to-md");
178
184
 
179
- // notion client not required
180
- const n2m = new notion2md();
185
+ // passing notion client to the option
186
+ const n2m = new NotionToMarkdown({ notionClient: notion });
181
187
 
182
188
  const result = n2m.blockToMarkdown(block);
183
189
  console.log(result);
@@ -189,44 +195,6 @@ console.log(result);
189
195
  ![image](https://media.giphy.com/media/Ju7l5y9osyymQ/giphy.gif)
190
196
  ```
191
197
 
192
- ## API
193
-
194
- > ### `toMarkdownString(mdBlock[])`
195
- >
196
- > - takes output of `pageToMarkdown` or `blocksToMarkdown` as argument
197
- > - converts to markdown string.
198
-
199
- > ### `pageToMarkdown(id,totalPage)`
200
- >
201
- > - Uses `blocksToMarkdown` internally.
202
- > - `id`(pageid) as input and converts all the blocks in the page to corresponding markdown object
203
- > - `totalPage` is the retrieve block children request number i.e `page_size Maximum = totalPage * 100`.
204
-
205
- > ### totalPage
206
- >
207
- > 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)).
208
- >
209
- > ### How to use `totalPage` arg ?
210
- >
211
- > - if the notion page contains less than or equal `100` blocks then `totalPage` arg is not required.
212
- > - 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.
213
-
214
- > ### `blocksToMarkdown(blocks,totalPage)`
215
- >
216
- > **Note**: requires <u>**notion-sdk-js**</u> unlike `blockToMarkdown`
217
- >
218
- > - `blocks`: array of notion blocks
219
- > - `totalPage`: the retrieve block children request number i.e `page_size Maximum = totalPage * 100`.
220
- > - deals with <u>**nested blocks**</u>
221
- > - uses `blockToMarkdown` internally.
222
-
223
- > ### `blockToMarkdown(block)`
224
- >
225
- > - Takes single notion block and converts to markdown string
226
- > - does not deal with nested notion blocks
227
- > - This method doesn't require the `notion-sdk-js`.
228
- > - Refer docs to know more about [notion blocks](https://developers.notion.com/reference/block)
229
-
230
198
  ## Contribution
231
199
 
232
200
  Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
@@ -3,8 +3,8 @@ import { Annotations, ListBlockChildrenResponseResult, ListBlockChildrenResponse
3
3
  * Converts a Notion page to Markdown.
4
4
  */
5
5
  export declare class NotionToMarkdown {
6
- private notionClient?;
7
- constructor(options?: NotionToMarkdownOptions);
6
+ private notionClient;
7
+ constructor(options: NotionToMarkdownOptions);
8
8
  /**
9
9
  * Converts Markdown Blocks to string
10
10
  * @param {MdBlock[]} mdBlocks - Array of markdown blocks
@@ -15,10 +15,10 @@ export declare class NotionToMarkdown {
15
15
  /**
16
16
  * Retrieves Notion Blocks based on ID and converts them to Markdown Blocks
17
17
  * @param {string} id - notion page id (not database id)
18
- * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=1)
18
+ * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=null)
19
19
  * @returns {Promise<MdBlock[]>} - List of markdown blocks
20
20
  */
21
- pageToMarkdown(id: string, totalPage?: number): Promise<MdBlock[]>;
21
+ pageToMarkdown(id: string, totalPage?: number | null): Promise<MdBlock[]>;
22
22
  /**
23
23
  * Converts list of Notion Blocks to Markdown Blocks
24
24
  * @param {ListBlockChildrenResponseResults | undefined} blocks - List of notion blocks
@@ -26,13 +26,13 @@ export declare class NotionToMarkdown {
26
26
  * @param {MdBlock[]} mdBlocks - Defines max depth of nesting
27
27
  * @returns {Promise<MdBlock[]>} - Array of markdown blocks with their children
28
28
  */
29
- blocksToMarkdown(blocks?: ListBlockChildrenResponseResults, totalPage?: number, mdBlocks?: MdBlock[]): Promise<MdBlock[]>;
29
+ blocksToMarkdown(blocks?: ListBlockChildrenResponseResults, totalPage?: number | null, mdBlocks?: MdBlock[]): Promise<MdBlock[]>;
30
30
  /**
31
31
  * Converts a Notion Block to a Markdown Block
32
32
  * @param {ListBlockChildrenResponseResult} block - single notion block
33
33
  * @returns {string} corresponding markdown string of the passed block
34
34
  */
35
- blockToMarkdown(block: ListBlockChildrenResponseResult): string;
35
+ blockToMarkdown(block: ListBlockChildrenResponseResult): Promise<string>;
36
36
  /**
37
37
  * Annoate text using provided annotations
38
38
  * @param {string} text - String to be annotated
@@ -1 +1 @@
1
- {"version":3,"file":"notion-to-md.d.ts","sourceRoot":"","sources":["../src/notion-to-md.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,+BAA+B,EAC/B,gCAAgC,EAChC,OAAO,EAEP,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAIjB;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAS;gBAElB,OAAO,CAAC,EAAE,uBAAuB;IAI7C;;;;;OAKG;IACH,gBAAgB,CAAC,QAAQ,GAAE,OAAO,EAAO,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM;IAe5E;;;;;OAKG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAY3E;;;;;;OAMG;IACG,gBAAgB,CACpB,MAAM,CAAC,EAAE,gCAAgC,EACzC,SAAS,GAAE,MAAU,EACrB,QAAQ,GAAE,OAAO,EAAO,GACvB,OAAO,CAAC,OAAO,EAAE,CAAC;IAkCrB;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,+BAA+B,GAAG,MAAM;IA8H/D;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM;CAsBlE"}
1
+ {"version":3,"file":"notion-to-md.d.ts","sourceRoot":"","sources":["../src/notion-to-md.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,+BAA+B,EAC/B,gCAAgC,EAChC,OAAO,EAEP,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAIjB;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,uBAAuB;IAI5C;;;;;OAKG;IACH,gBAAgB,CAAC,QAAQ,GAAE,OAAO,EAAO,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM;IAe5E;;;;;OAKG;IACG,cAAc,CAClB,EAAE,EAAE,MAAM,EACV,SAAS,GAAE,MAAM,GAAG,IAAW,GAC9B,OAAO,CAAC,OAAO,EAAE,CAAC;IAarB;;;;;;OAMG;IACG,gBAAgB,CACpB,MAAM,CAAC,EAAE,gCAAgC,EACzC,SAAS,GAAE,MAAM,GAAG,IAAW,EAC/B,QAAQ,GAAE,OAAO,EAAO,GACvB,OAAO,CAAC,OAAO,EAAE,CAAC;IAsCrB;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,+BAA+B;IA+L5D;;;;;OAKG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM;CAsBlE"}
@@ -27,7 +27,7 @@ const notion_1 = require("./utils/notion");
27
27
  */
28
28
  class NotionToMarkdown {
29
29
  constructor(options) {
30
- this.notionClient = options ? options.notionClient : undefined;
30
+ this.notionClient = options.notionClient;
31
31
  }
32
32
  /**
33
33
  * Converts Markdown Blocks to string
@@ -52,15 +52,13 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
52
52
  /**
53
53
  * Retrieves Notion Blocks based on ID and converts them to Markdown Blocks
54
54
  * @param {string} id - notion page id (not database id)
55
- * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=1)
55
+ * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=null)
56
56
  * @returns {Promise<MdBlock[]>} - List of markdown blocks
57
57
  */
58
- async pageToMarkdown(id, totalPage = 1) {
58
+ async pageToMarkdown(id, totalPage = null) {
59
59
  if (!this.notionClient) {
60
60
  throw new Error("notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md");
61
61
  }
62
- if (!id)
63
- throw new Error("pageToMarkdown takes page_id as argument");
64
62
  const blocks = await (0, notion_1.getBlockChildren)(this.notionClient, id, totalPage);
65
63
  const parsedData = await this.blocksToMarkdown(blocks);
66
64
  return parsedData;
@@ -72,7 +70,7 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
72
70
  * @param {MdBlock[]} mdBlocks - Defines max depth of nesting
73
71
  * @returns {Promise<MdBlock[]>} - Array of markdown blocks with their children
74
72
  */
75
- async blocksToMarkdown(blocks, totalPage = 1, mdBlocks = []) {
73
+ async blocksToMarkdown(blocks, totalPage = null, mdBlocks = []) {
76
74
  if (!this.notionClient) {
77
75
  throw new Error("notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md");
78
76
  }
@@ -82,12 +80,15 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
82
80
  let block = blocks[i];
83
81
  if ("has_children" in block && block.has_children) {
84
82
  let child_blocks = await (0, notion_1.getBlockChildren)(this.notionClient, block.id, totalPage);
85
- mdBlocks.push({ parent: this.blockToMarkdown(block), children: [] });
83
+ mdBlocks.push({
84
+ parent: await this.blockToMarkdown(block),
85
+ children: [],
86
+ });
86
87
  let l = mdBlocks.length;
87
88
  await this.blocksToMarkdown(child_blocks, totalPage, mdBlocks[l - 1].children);
88
89
  continue;
89
90
  }
90
- let tmp = this.blockToMarkdown(block);
91
+ let tmp = await this.blockToMarkdown(block);
91
92
  mdBlocks.push({ parent: tmp, children: [] });
92
93
  }
93
94
  return mdBlocks;
@@ -97,21 +98,26 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
97
98
  * @param {ListBlockChildrenResponseResult} block - single notion block
98
99
  * @returns {string} corresponding markdown string of the passed block
99
100
  */
100
- blockToMarkdown(block) {
101
+ async blockToMarkdown(block) {
101
102
  if (!("type" in block))
102
103
  return "";
103
104
  let parsedData = "";
104
105
  const { type } = block;
106
+ // console.log({ block });
105
107
  switch (type) {
106
- case "image": {
107
- let blockContent = block.image;
108
- const image_type = blockContent.type;
109
- if (image_type === "external")
110
- return md.image("image", blockContent.external.url);
111
- if (image_type === "file")
112
- return md.image("image", blockContent.file.url);
108
+ case "image":
109
+ {
110
+ let blockContent = block.image;
111
+ const image_caption_plain = blockContent.caption
112
+ .map((item) => item.plain_text)
113
+ .join("");
114
+ const image_type = blockContent.type;
115
+ if (image_type === "external")
116
+ return md.image(image_caption_plain, blockContent.external.url);
117
+ if (image_type === "file")
118
+ return md.image(image_caption_plain, blockContent.file.url);
119
+ }
113
120
  break;
114
- }
115
121
  case "divider": {
116
122
  return md.divider();
117
123
  }
@@ -120,36 +126,66 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
120
126
  }
121
127
  case "video":
122
128
  case "file":
123
- case "pdf": {
124
- let blockContent;
125
- if (type === "video")
126
- blockContent = block.video;
127
- if (type === "file")
128
- blockContent = block.file;
129
- if (type === "pdf")
130
- blockContent = block.pdf;
131
- if (blockContent) {
132
- const file_type = blockContent.type;
133
- if (file_type === "external")
134
- return md.link("image", blockContent.external.url);
135
- if (file_type === "file")
136
- return md.link("image", blockContent.file.url);
129
+ case "pdf":
130
+ {
131
+ let blockContent;
132
+ if (type === "video")
133
+ blockContent = block.video;
134
+ if (type === "file")
135
+ blockContent = block.file;
136
+ if (type === "pdf")
137
+ blockContent = block.pdf;
138
+ if (blockContent) {
139
+ const file_type = blockContent.type;
140
+ if (file_type === "external")
141
+ return md.link("image", blockContent.external.url);
142
+ if (file_type === "file")
143
+ return md.link("image", blockContent.file.url);
144
+ }
137
145
  }
138
146
  break;
139
- }
140
147
  case "bookmark":
141
148
  case "embed":
142
- case "link_preview": {
143
- let blockContent;
144
- if (type === "bookmark")
145
- blockContent = block.bookmark;
146
- if (type === "embed")
147
- blockContent = block.embed;
148
- if (type === "link_preview")
149
- blockContent = block.link_preview;
150
- if (blockContent)
151
- return md.link(type, blockContent.url);
149
+ case "link_preview":
150
+ {
151
+ let blockContent;
152
+ if (type === "bookmark")
153
+ blockContent = block.bookmark;
154
+ if (type === "embed")
155
+ blockContent = block.embed;
156
+ if (type === "link_preview")
157
+ blockContent = block.link_preview;
158
+ if (blockContent)
159
+ return md.link(type, blockContent.url);
160
+ }
152
161
  break;
162
+ case "table": {
163
+ const { id, has_children } = block;
164
+ let tableArr = [];
165
+ if (has_children) {
166
+ const tableRows = await (0, notion_1.getBlockChildren)(this.notionClient, id, 100);
167
+ // console.log(">>", tableRows);
168
+ let rowsPromise = tableRows === null || tableRows === void 0 ? void 0 : tableRows.map(async (row) => {
169
+ const { type } = row;
170
+ const cells = row[type]["cells"];
171
+ /**
172
+ * this is more like a hack since matching the type text was
173
+ * difficult. So converting each cell to paragraph type to
174
+ * reuse the blockToMarkdown function
175
+ */
176
+ let cellStringPromise = cells.map(async (cell) => await this.blockToMarkdown({
177
+ type: "paragraph",
178
+ paragraph: { text: cell },
179
+ }));
180
+ const cellStringArr = await Promise.all(cellStringPromise);
181
+ // console.log("~~", cellStringArr);
182
+ tableArr.push(cellStringArr);
183
+ // console.log(tableArr);
184
+ });
185
+ await Promise.all(rowsPromise || []);
186
+ }
187
+ parsedData = md.table(tableArr);
188
+ return parsedData;
153
189
  }
154
190
  // Rest of the types
155
191
  // "paragraph"
@@ -189,35 +225,47 @@ ${md.addTabSpace(mdBlocks.parent, nestingLevel)}
189
225
  }
190
226
  }
191
227
  switch (type) {
192
- case "code": {
193
- parsedData = md.codeBlock(parsedData, block[type].language);
228
+ case "code":
229
+ {
230
+ parsedData = md.codeBlock(parsedData, block[type].language);
231
+ }
194
232
  break;
195
- }
196
- case "heading_1": {
197
- parsedData = md.heading1(parsedData);
233
+ case "heading_1":
234
+ {
235
+ parsedData = md.heading1(parsedData);
236
+ }
198
237
  break;
199
- }
200
- case "heading_2": {
201
- parsedData = md.heading2(parsedData);
238
+ case "heading_2":
239
+ {
240
+ parsedData = md.heading2(parsedData);
241
+ }
202
242
  break;
203
- }
204
- case "heading_3": {
205
- parsedData = md.heading3(parsedData);
243
+ case "heading_3":
244
+ {
245
+ parsedData = md.heading3(parsedData);
246
+ }
206
247
  break;
207
- }
208
- case "quote": {
209
- parsedData = md.quote(parsedData);
248
+ case "quote":
249
+ {
250
+ parsedData = md.quote(parsedData);
251
+ }
252
+ break;
253
+ case "callout":
254
+ {
255
+ parsedData = md.callout(parsedData, block[type].icon);
256
+ }
210
257
  break;
211
- }
212
258
  case "bulleted_list_item":
213
- case "numbered_list_item": {
214
- parsedData = md.bullet(parsedData);
259
+ case "numbered_list_item":
260
+ {
261
+ parsedData = md.bullet(parsedData);
262
+ }
215
263
  break;
216
- }
217
- case "to_do": {
218
- parsedData = md.todo(parsedData, block.to_do.checked);
264
+ case "to_do":
265
+ {
266
+ parsedData = md.todo(parsedData, block.to_do.checked);
267
+ }
219
268
  break;
220
- }
221
269
  }
222
270
  return parsedData;
223
271
  }
@@ -1 +1 @@
1
- {"version":3,"file":"notion-to-md.js","sourceRoot":"","sources":["../src/notion-to-md.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client } from \"@notionhq/client\";\nimport {\n Annotations,\n ListBlockChildrenResponseResult,\n ListBlockChildrenResponseResults,\n MdBlock,\n Text,\n NotionToMarkdownOptions,\n} from \"./types\";\nimport * as md from \"./utils/md\";\nimport { getBlockChildren } from \"./utils/notion\";\n\n/**\n * Converts a Notion page to Markdown.\n */\nexport class NotionToMarkdown {\n private notionClient?: Client;\n\n constructor(options?: NotionToMarkdownOptions) {\n this.notionClient = options ? options.notionClient : undefined;\n }\n\n /**\n * Converts Markdown Blocks to string\n * @param {MdBlock[]} mdBlocks - Array of markdown blocks\n * @param {number} nestingLevel - Defines max depth of nesting\n * @returns {string} - Returns markdown string\n */\n toMarkdownString(mdBlocks: MdBlock[] = [], nestingLevel: number = 0): string {\n let mdString = \"\";\n mdBlocks.forEach((mdBlocks) => {\n if (mdBlocks.parent) {\n mdString += `\n${md.addTabSpace(mdBlocks.parent, nestingLevel)}\n`;\n }\n if (mdBlocks.children && mdBlocks.children.length > 0) {\n mdString += this.toMarkdownString(mdBlocks.children, nestingLevel + 1);\n }\n });\n return mdString;\n }\n\n /**\n * Retrieves Notion Blocks based on ID and converts them to Markdown Blocks\n * @param {string} id - notion page id (not database id)\n * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=1)\n * @returns {Promise<MdBlock[]>} - List of markdown blocks\n */\n async pageToMarkdown(id: string, totalPage: number = 1): Promise<MdBlock[]> {\n if (!this.notionClient) {\n throw new Error(\n \"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md\"\n );\n }\n if (!id) throw new Error(\"pageToMarkdown takes page_id as argument\");\n const blocks = await getBlockChildren(this.notionClient, id, totalPage);\n const parsedData = await this.blocksToMarkdown(blocks);\n return parsedData;\n }\n\n /**\n * Converts list of Notion Blocks to Markdown Blocks\n * @param {ListBlockChildrenResponseResults | undefined} blocks - List of notion blocks\n * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100\n * @param {MdBlock[]} mdBlocks - Defines max depth of nesting\n * @returns {Promise<MdBlock[]>} - Array of markdown blocks with their children\n */\n async blocksToMarkdown(\n blocks?: ListBlockChildrenResponseResults,\n totalPage: number = 1,\n mdBlocks: MdBlock[] = []\n ): Promise<MdBlock[]> {\n if (!this.notionClient) {\n throw new Error(\n \"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md\"\n );\n }\n\n if (!blocks) return mdBlocks;\n\n for (let i = 0; i < blocks.length; i++) {\n let block = blocks[i];\n if (\"has_children\" in block && block.has_children) {\n let child_blocks = await getBlockChildren(\n this.notionClient,\n block.id,\n totalPage\n );\n mdBlocks.push({ parent: this.blockToMarkdown(block), children: [] });\n\n let l = mdBlocks.length;\n await this.blocksToMarkdown(\n child_blocks,\n totalPage,\n mdBlocks[l - 1].children\n );\n continue;\n }\n let tmp = this.blockToMarkdown(block);\n\n mdBlocks.push({ parent: tmp, children: [] });\n }\n return mdBlocks;\n }\n\n /**\n * Converts a Notion Block to a Markdown Block\n * @param {ListBlockChildrenResponseResult} block - single notion block\n * @returns {string} corresponding markdown string of the passed block\n */\n blockToMarkdown(block: ListBlockChildrenResponseResult): string {\n if (!(\"type\" in block)) return \"\";\n\n let parsedData = \"\";\n const { type } = block;\n\n switch (type) {\n case \"image\": {\n let blockContent = block.image;\n const image_type = blockContent.type;\n if (image_type === \"external\")\n return md.image(\"image\", blockContent.external.url);\n if (image_type === \"file\")\n return md.image(\"image\", blockContent.file.url);\n break;\n }\n case \"divider\": {\n return md.divider();\n }\n case \"equation\": {\n return md.codeBlock(block.equation.expression);\n }\n case \"video\":\n case \"file\":\n case \"pdf\": {\n let blockContent;\n if (type === \"video\") blockContent = block.video;\n if (type === \"file\") blockContent = block.file;\n if (type === \"pdf\") blockContent = block.pdf;\n if (blockContent) {\n const file_type = blockContent.type;\n if (file_type === \"external\")\n return md.link(\"image\", blockContent.external.url);\n if (file_type === \"file\")\n return md.link(\"image\", blockContent.file.url);\n }\n break;\n }\n case \"bookmark\":\n case \"embed\":\n case \"link_preview\": {\n let blockContent;\n if (type === \"bookmark\") blockContent = block.bookmark;\n if (type === \"embed\") blockContent = block.embed;\n if (type === \"link_preview\") blockContent = block.link_preview;\n if (blockContent) return md.link(type, blockContent.url);\n break;\n }\n\n // Rest of the types\n // \"paragraph\"\n // \"heading_1\"\n // \"heading_2\"\n // \"heading_3\"\n // \"bulleted_list_item\"\n // \"numbered_list_item\"\n // \"quote\"\n // \"to_do\"\n // \"toggle\"\n // \"template\"\n // \"synced_block\"\n // \"child_page\"\n // \"child_database\"\n // \"code\"\n // \"callout\"\n // \"breadcrumb\"\n // \"table_of_contents\"\n // \"column_list\"\n // \"column\"\n // \"link_to_page\"\n // \"audio\"\n // \"unsupported\"\n default: {\n // In this case typescript is not able to index the types properly, hence ignoring the error\n\n // @ts-ignore\n let blockContent = block[type].text || [];\n blockContent.map((content: Text) => {\n const annotations = content.annotations;\n let plain_text = content.plain_text;\n\n plain_text = this.annotatePlainText(plain_text, annotations);\n\n if (content[\"href\"])\n plain_text = md.link(plain_text, content[\"href\"]);\n\n parsedData += plain_text;\n });\n }\n }\n\n switch (type) {\n case \"code\": {\n parsedData = md.codeBlock(parsedData, block[type].language);\n break;\n }\n case \"heading_1\": {\n parsedData = md.heading1(parsedData);\n break;\n }\n case \"heading_2\": {\n parsedData = md.heading2(parsedData);\n break;\n }\n case \"heading_3\": {\n parsedData = md.heading3(parsedData);\n break;\n }\n case \"quote\": {\n parsedData = md.quote(parsedData);\n break;\n }\n case \"bulleted_list_item\":\n case \"numbered_list_item\": {\n parsedData = md.bullet(parsedData);\n break;\n }\n case \"to_do\": {\n parsedData = md.todo(parsedData, block.to_do.checked);\n break;\n }\n }\n\n return parsedData;\n }\n\n /**\n * Annoate text using provided annotations\n * @param {string} text - String to be annotated\n * @param {Annotations} annotations - Annotation object of a notion block\n * @returns {string} - Annotated text\n */\n annotatePlainText(text: string, annotations: Annotations): string {\n // if text is all spaces, don't annotate\n if (text.match(/^\\s*$/)) return text;\n\n const leadingSpaceMatch = text.match(/^(\\s*)/);\n const trailingSpaceMatch = text.match(/(\\s*)$/);\n\n const leading_space = leadingSpaceMatch ? leadingSpaceMatch[0] : \"\";\n const trailing_space = trailingSpaceMatch ? trailingSpaceMatch[0] : \"\";\n\n text = text.trim();\n\n if (text !== \"\") {\n if (annotations.code) text = md.inlineCode(text);\n if (annotations.bold) text = md.bold(text);\n if (annotations.italic) text = md.italic(text);\n if (annotations.strikethrough) text = md.strikethrough(text);\n if (annotations.underline) text = md.underline(text);\n }\n\n return leading_space + text + trailing_space;\n }\n}\n"]}
1
+ {"version":3,"file":"notion-to-md.js","sourceRoot":"","sources":["../src/notion-to-md.ts"],"names":[],"mappings":"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","sourcesContent":["import { Client } from \"@notionhq/client\";\nimport {\n Annotations,\n ListBlockChildrenResponseResult,\n ListBlockChildrenResponseResults,\n MdBlock,\n Text,\n NotionToMarkdownOptions,\n} from \"./types\";\nimport * as md from \"./utils/md\";\nimport { getBlockChildren } from \"./utils/notion\";\n\n/**\n * Converts a Notion page to Markdown.\n */\nexport class NotionToMarkdown {\n private notionClient: Client;\n\n constructor(options: NotionToMarkdownOptions) {\n this.notionClient = options.notionClient;\n }\n\n /**\n * Converts Markdown Blocks to string\n * @param {MdBlock[]} mdBlocks - Array of markdown blocks\n * @param {number} nestingLevel - Defines max depth of nesting\n * @returns {string} - Returns markdown string\n */\n toMarkdownString(mdBlocks: MdBlock[] = [], nestingLevel: number = 0): string {\n let mdString = \"\";\n mdBlocks.forEach((mdBlocks) => {\n if (mdBlocks.parent) {\n mdString += `\n${md.addTabSpace(mdBlocks.parent, nestingLevel)}\n`;\n }\n if (mdBlocks.children && mdBlocks.children.length > 0) {\n mdString += this.toMarkdownString(mdBlocks.children, nestingLevel + 1);\n }\n });\n return mdString;\n }\n\n /**\n * Retrieves Notion Blocks based on ID and converts them to Markdown Blocks\n * @param {string} id - notion page id (not database id)\n * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100 (Default=null)\n * @returns {Promise<MdBlock[]>} - List of markdown blocks\n */\n async pageToMarkdown(\n id: string,\n totalPage: number | null = null\n ): Promise<MdBlock[]> {\n if (!this.notionClient) {\n throw new Error(\n \"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md\"\n );\n }\n\n const blocks = await getBlockChildren(this.notionClient, id, totalPage);\n\n const parsedData = await this.blocksToMarkdown(blocks);\n return parsedData;\n }\n\n /**\n * Converts list of Notion Blocks to Markdown Blocks\n * @param {ListBlockChildrenResponseResults | undefined} blocks - List of notion blocks\n * @param {number} totalPage - Retrieve block children request number, page_size Maximum = totalPage * 100\n * @param {MdBlock[]} mdBlocks - Defines max depth of nesting\n * @returns {Promise<MdBlock[]>} - Array of markdown blocks with their children\n */\n async blocksToMarkdown(\n blocks?: ListBlockChildrenResponseResults,\n totalPage: number | null = null,\n mdBlocks: MdBlock[] = []\n ): Promise<MdBlock[]> {\n if (!this.notionClient) {\n throw new Error(\n \"notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md\"\n );\n }\n\n if (!blocks) return mdBlocks;\n\n for (let i = 0; i < blocks.length; i++) {\n let block = blocks[i];\n\n if (\"has_children\" in block && block.has_children) {\n let child_blocks = await getBlockChildren(\n this.notionClient,\n block.id,\n totalPage\n );\n mdBlocks.push({\n parent: await this.blockToMarkdown(block),\n children: [],\n });\n\n let l = mdBlocks.length;\n await this.blocksToMarkdown(\n child_blocks,\n totalPage,\n mdBlocks[l - 1].children\n );\n continue;\n }\n let tmp = await this.blockToMarkdown(block);\n\n mdBlocks.push({ parent: tmp, children: [] });\n }\n return mdBlocks;\n }\n\n /**\n * Converts a Notion Block to a Markdown Block\n * @param {ListBlockChildrenResponseResult} block - single notion block\n * @returns {string} corresponding markdown string of the passed block\n */\n async blockToMarkdown(block: ListBlockChildrenResponseResult) {\n if (!(\"type\" in block)) return \"\";\n\n let parsedData = \"\";\n const { type } = block;\n // console.log({ block });\n\n switch (type) {\n case \"image\":\n {\n let blockContent = block.image;\n const image_caption_plain = blockContent.caption\n .map((item) => item.plain_text)\n .join(\"\");\n const image_type = blockContent.type;\n if (image_type === \"external\")\n return md.image(image_caption_plain, blockContent.external.url);\n if (image_type === \"file\")\n return md.image(image_caption_plain, blockContent.file.url);\n }\n break;\n\n case \"divider\": {\n return md.divider();\n }\n\n case \"equation\": {\n return md.codeBlock(block.equation.expression);\n }\n\n case \"video\":\n case \"file\":\n case \"pdf\":\n {\n let blockContent;\n if (type === \"video\") blockContent = block.video;\n if (type === \"file\") blockContent = block.file;\n if (type === \"pdf\") blockContent = block.pdf;\n if (blockContent) {\n const file_type = blockContent.type;\n if (file_type === \"external\")\n return md.link(\"image\", blockContent.external.url);\n if (file_type === \"file\")\n return md.link(\"image\", blockContent.file.url);\n }\n }\n break;\n\n case \"bookmark\":\n case \"embed\":\n case \"link_preview\":\n {\n let blockContent;\n if (type === \"bookmark\") blockContent = block.bookmark;\n if (type === \"embed\") blockContent = block.embed;\n if (type === \"link_preview\") blockContent = block.link_preview;\n if (blockContent) return md.link(type, blockContent.url);\n }\n break;\n\n case \"table\": {\n const { id, has_children } = block;\n let tableArr: string[][] = [];\n if (has_children) {\n const tableRows = await getBlockChildren(this.notionClient, id, 100);\n // console.log(\">>\", tableRows);\n let rowsPromise = tableRows?.map(async (row) => {\n const { type } = row as any;\n const cells = (row as any)[type][\"cells\"];\n\n /**\n * this is more like a hack since matching the type text was\n * difficult. So converting each cell to paragraph type to\n * reuse the blockToMarkdown function\n */\n let cellStringPromise = cells.map(\n async (cell: any) =>\n await this.blockToMarkdown({\n type: \"paragraph\",\n paragraph: { text: cell },\n } as ListBlockChildrenResponseResult)\n );\n\n const cellStringArr = await Promise.all(cellStringPromise);\n // console.log(\"~~\", cellStringArr);\n tableArr.push(cellStringArr);\n // console.log(tableArr);\n });\n await Promise.all(rowsPromise || []);\n }\n parsedData = md.table(tableArr);\n return parsedData;\n }\n\n // Rest of the types\n // \"paragraph\"\n // \"heading_1\"\n // \"heading_2\"\n // \"heading_3\"\n // \"bulleted_list_item\"\n // \"numbered_list_item\"\n // \"quote\"\n // \"to_do\"\n // \"toggle\"\n // \"template\"\n // \"synced_block\"\n // \"child_page\"\n // \"child_database\"\n // \"code\"\n // \"callout\"\n // \"breadcrumb\"\n // \"table_of_contents\"\n // \"column_list\"\n // \"column\"\n // \"link_to_page\"\n // \"audio\"\n // \"unsupported\"\n\n default: {\n // In this case typescript is not able to index the types properly, hence ignoring the error\n\n // @ts-ignore\n let blockContent = block[type].text || [];\n blockContent.map((content: Text) => {\n const annotations = content.annotations;\n let plain_text = content.plain_text;\n\n plain_text = this.annotatePlainText(plain_text, annotations);\n\n if (content[\"href\"])\n plain_text = md.link(plain_text, content[\"href\"]);\n\n parsedData += plain_text;\n });\n }\n }\n\n switch (type) {\n case \"code\":\n {\n parsedData = md.codeBlock(parsedData, block[type].language);\n }\n break;\n\n case \"heading_1\":\n {\n parsedData = md.heading1(parsedData);\n }\n break;\n\n case \"heading_2\":\n {\n parsedData = md.heading2(parsedData);\n }\n break;\n\n case \"heading_3\":\n {\n parsedData = md.heading3(parsedData);\n }\n break;\n\n case \"quote\":\n {\n parsedData = md.quote(parsedData);\n }\n break;\n\n case \"callout\":\n {\n parsedData = md.callout(parsedData, block[type].icon);\n }\n break;\n\n case \"bulleted_list_item\":\n case \"numbered_list_item\":\n {\n parsedData = md.bullet(parsedData);\n }\n break;\n\n case \"to_do\":\n {\n parsedData = md.todo(parsedData, block.to_do.checked);\n }\n break;\n }\n\n return parsedData;\n }\n\n /**\n * Annoate text using provided annotations\n * @param {string} text - String to be annotated\n * @param {Annotations} annotations - Annotation object of a notion block\n * @returns {string} - Annotated text\n */\n annotatePlainText(text: string, annotations: Annotations): string {\n // if text is all spaces, don't annotate\n if (text.match(/^\\s*$/)) return text;\n\n const leadingSpaceMatch = text.match(/^(\\s*)/);\n const trailingSpaceMatch = text.match(/(\\s*)$/);\n\n const leading_space = leadingSpaceMatch ? leadingSpaceMatch[0] : \"\";\n const trailing_space = trailingSpaceMatch ? trailingSpaceMatch[0] : \"\";\n\n text = text.trim();\n\n if (text !== \"\") {\n if (annotations.code) text = md.inlineCode(text);\n if (annotations.bold) text = md.bold(text);\n if (annotations.italic) text = md.italic(text);\n if (annotations.strikethrough) text = md.strikethrough(text);\n if (annotations.underline) text = md.underline(text);\n }\n\n return leading_space + text + trailing_space;\n }\n}\n"]}
@@ -30,4 +30,19 @@ export declare type Text = {
30
30
  plain_text: string;
31
31
  href: string | null;
32
32
  };
33
+ export declare type CalloutIcon = {
34
+ type: "emoji";
35
+ emoji?: string;
36
+ } | {
37
+ type: "external";
38
+ external?: {
39
+ url: string;
40
+ };
41
+ } | {
42
+ type: "file";
43
+ file: {
44
+ url: string;
45
+ expiry_time: string;
46
+ };
47
+ } | null;
33
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,oBAAY,gCAAgC,GAC1C,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAEvC,oBAAY,+BAA+B,GACzC,gCAAgC,CAAC,CAAC,CAAC,CAAC;AAEtC,oBAAY,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,oBAAY,OAAO,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EACD,SAAS,GACT,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,MAAM,GACN,QAAQ,GACR,MAAM,GACN,KAAK,GACL,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,CAAC;CACtB,CAAC;AAEF,oBAAY,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,GAAG,EAAE,WAAW,CAAC;SAClB,GAAG,IAAI,CAAC;KACV,CAAC;IACF,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,oBAAY,gCAAgC,GAC1C,yBAAyB,CAAC,SAAS,CAAC,CAAC;AAEvC,oBAAY,+BAA+B,GACzC,gCAAgC,CAAC,CAAC,CAAC,CAAC;AAEtC,oBAAY,WAAW,GAAG,MAAM,CAAC;AAEjC,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,oBAAY,OAAO,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB,CAAC;AAEF,oBAAY,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EACD,SAAS,GACT,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,MAAM,GACN,QAAQ,GACR,MAAM,GACN,KAAK,GACL,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,GACnB,mBAAmB,GACnB,kBAAkB,GAClB,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,CAAC;CACtB,CAAC;AAEF,oBAAY,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE;YACJ,GAAG,EAAE,WAAW,CAAC;SAClB,GAAG,IAAI,CAAC;KACV,CAAC;IACF,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,oBAAY,WAAW,GAAG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAG,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;KAAE,CAAC;CAAE,GAAG,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import { ListBlockChildrenResponse } from \"@notionhq/client/build/src/api-endpoints\";\nimport { Client } from \"@notionhq/client\";\n\nexport type ListBlockChildrenResponseResults =\n ListBlockChildrenResponse[\"results\"];\n\nexport type ListBlockChildrenResponseResult =\n ListBlockChildrenResponseResults[0];\n\nexport type TextRequest = string;\n\nexport interface NotionToMarkdownOptions {\n notionClient: Client;\n}\n\nexport type MdBlock = {\n parent: string;\n children: MdBlock[];\n};\n\nexport type Annotations = {\n bold: boolean;\n italic: boolean;\n strikethrough: boolean;\n underline: boolean;\n code: boolean;\n color:\n | \"default\"\n | \"gray\"\n | \"brown\"\n | \"orange\"\n | \"yellow\"\n | \"green\"\n | \"blue\"\n | \"purple\"\n | \"pink\"\n | \"red\"\n | \"gray_background\"\n | \"brown_background\"\n | \"orange_background\"\n | \"yellow_background\"\n | \"green_background\"\n | \"blue_background\"\n | \"purple_background\"\n | \"pink_background\"\n | \"red_background\";\n};\n\nexport type Text = {\n type: \"text\";\n text: {\n content: string;\n link: {\n url: TextRequest;\n } | null;\n };\n annotations: Annotations;\n plain_text: string;\n href: string | null;\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import { ListBlockChildrenResponse } from \"@notionhq/client/build/src/api-endpoints\";\nimport { Client } from \"@notionhq/client\";\n\nexport type ListBlockChildrenResponseResults =\n ListBlockChildrenResponse[\"results\"];\n\nexport type ListBlockChildrenResponseResult =\n ListBlockChildrenResponseResults[0];\n\nexport type TextRequest = string;\n\nexport interface NotionToMarkdownOptions {\n notionClient: Client;\n}\n\nexport type MdBlock = {\n parent: string;\n children: MdBlock[];\n};\n\nexport type Annotations = {\n bold: boolean;\n italic: boolean;\n strikethrough: boolean;\n underline: boolean;\n code: boolean;\n color:\n | \"default\"\n | \"gray\"\n | \"brown\"\n | \"orange\"\n | \"yellow\"\n | \"green\"\n | \"blue\"\n | \"purple\"\n | \"pink\"\n | \"red\"\n | \"gray_background\"\n | \"brown_background\"\n | \"orange_background\"\n | \"yellow_background\"\n | \"green_background\"\n | \"blue_background\"\n | \"purple_background\"\n | \"pink_background\"\n | \"red_background\";\n};\n\nexport type Text = {\n type: \"text\";\n text: {\n content: string;\n link: {\n url: TextRequest;\n } | null;\n };\n annotations: Annotations;\n plain_text: string;\n href: string | null;\n};\n\nexport type CalloutIcon = { type: \"emoji\"; emoji?: string; } | { type: \"external\"; external?: { url: string }; } | { type: \"file\"; file: { url: string; expiry_time: string; }; } | null;"]}
@@ -1,3 +1,4 @@
1
+ import { CalloutIcon } from '../types';
1
2
  export declare const inlineCode: (text: string) => string;
2
3
  export declare const bold: (text: string) => string;
3
4
  export declare const italic: (text: string) => string;
@@ -9,9 +10,13 @@ export declare const heading1: (text: string) => string;
9
10
  export declare const heading2: (text: string) => string;
10
11
  export declare const heading3: (text: string) => string;
11
12
  export declare const quote: (text: string) => string;
13
+ export declare const callout: (text: string, icon?: CalloutIcon | undefined) => string;
12
14
  export declare const bullet: (text: string) => string;
13
15
  export declare const todo: (text: string, checked: boolean) => string;
14
16
  export declare const image: (alt: string, href: string) => string;
15
17
  export declare const addTabSpace: (text: string, n?: number) => string;
16
18
  export declare const divider: () => string;
19
+ export declare const tableRowHeader: (row: string[]) => string;
20
+ export declare const tableRowBody: (row: string[]) => string;
21
+ export declare const table: (cells: string[][]) => string;
17
22
  //# sourceMappingURL=md.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"md.d.ts","sourceRoot":"","sources":["../../src/utils/md.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,SAAU,MAAM,WAEtC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,WAEhC,CAAC;AAEF,eAAO,MAAM,MAAM,SAAU,MAAM,WAElC,CAAC;AAEF,eAAO,MAAM,aAAa,SAAU,MAAM,WAEzC,CAAC;AAEF,eAAO,MAAM,SAAS,SAAU,MAAM,WAErC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,QAAQ,MAAM,WAE9C,CAAC;AAEF,eAAO,MAAM,SAAS,SAAU,MAAM,0CAIrC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAU,MAAM,WAGjC,CAAC;AAEF,eAAO,MAAM,MAAM,SAAU,MAAM,WAElC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,WAAW,OAAO,WAElD,CAAC;AAEF,eAAO,MAAM,KAAK,QAAS,MAAM,QAAQ,MAAM,WAE9C,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,uBAIvC,CAAC;AAEF,eAAO,MAAM,OAAO,cAEnB,CAAC"}
1
+ {"version":3,"file":"md.d.ts","sourceRoot":"","sources":["../../src/utils/md.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,eAAO,MAAM,UAAU,SAAU,MAAM,WAEtC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,WAEhC,CAAC;AAEF,eAAO,MAAM,MAAM,SAAU,MAAM,WAElC,CAAC;AAEF,eAAO,MAAM,aAAa,SAAU,MAAM,WAEzC,CAAC;AAEF,eAAO,MAAM,SAAS,SAAU,MAAM,WAErC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,QAAQ,MAAM,WAE9C,CAAC;AAEF,eAAO,MAAM,SAAS,SAAU,MAAM,0CAIrC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAEpC,CAAC;AAEF,eAAO,MAAM,KAAK,SAAU,MAAM,WAGjC,CAAC;AAEF,eAAO,MAAM,OAAO,SAAU,MAAM,2CAQnC,CAAC;AAEF,eAAO,MAAM,MAAM,SAAU,MAAM,WAElC,CAAC;AAEF,eAAO,MAAM,IAAI,SAAU,MAAM,WAAW,OAAO,WAElD,CAAC;AAEF,eAAO,MAAM,KAAK,QAAS,MAAM,QAAQ,MAAM,WAE9C,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,uBASvC,CAAC;AAEF,eAAO,MAAM,OAAO,cAEnB,CAAC;AAEF,eAAO,MAAM,cAAc,QAAS,MAAM,EAAE,WAI3C,CAAC;AAEF,eAAO,MAAM,YAAY,QAAS,MAAM,EAAE,WAEzC,CAAC;AAEF,eAAO,MAAM,KAAK,UAAW,MAAM,EAAE,EAAE,WAKtC,CAAC"}
package/build/utils/md.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.divider = exports.addTabSpace = exports.image = exports.todo = exports.bullet = exports.quote = exports.heading3 = exports.heading2 = exports.heading1 = exports.codeBlock = exports.link = exports.underline = exports.strikethrough = exports.italic = exports.bold = exports.inlineCode = void 0;
3
+ exports.table = exports.tableRowBody = exports.tableRowHeader = exports.divider = exports.addTabSpace = exports.image = exports.todo = exports.bullet = exports.callout = exports.quote = exports.heading3 = exports.heading2 = exports.heading1 = exports.codeBlock = exports.link = exports.underline = exports.strikethrough = exports.italic = exports.bold = exports.inlineCode = void 0;
4
4
  const inlineCode = (text) => {
5
5
  return `\`${text}\``;
6
6
  };
@@ -48,6 +48,15 @@ const quote = (text) => {
48
48
  return `> ${text.replace(/\n/g, " \n>")}`;
49
49
  };
50
50
  exports.quote = quote;
51
+ const callout = (text, icon) => {
52
+ let emoji;
53
+ if ((icon === null || icon === void 0 ? void 0 : icon.type) === 'emoji') {
54
+ emoji = icon.emoji;
55
+ }
56
+ // the replace is done to handle multiple lines
57
+ return `> ${emoji ? emoji + ' ' : ''}${text.replace(/\n/g, " \n>")}`;
58
+ };
59
+ exports.callout = callout;
51
60
  const bullet = (text) => {
52
61
  return `- ${text}`;
53
62
  };
@@ -62,8 +71,14 @@ const image = (alt, href) => {
62
71
  exports.image = image;
63
72
  const addTabSpace = (text, n = 0) => {
64
73
  const tab = " ";
65
- for (let i = 0; i < n; i++)
66
- text = tab + text;
74
+ for (let i = 0; i < n; i++) {
75
+ if (text.includes("\n")) {
76
+ const multiLineText = text.split(/(?<=\n)/).join(tab);
77
+ text = tab + multiLineText;
78
+ }
79
+ else
80
+ text = tab + text;
81
+ }
67
82
  return text;
68
83
  };
69
84
  exports.addTabSpace = addTabSpace;
@@ -71,4 +86,19 @@ const divider = () => {
71
86
  return "---";
72
87
  };
73
88
  exports.divider = divider;
89
+ const tableRowHeader = (row) => {
90
+ let header = row.join("|");
91
+ let divider = row.map((_) => "---").join("|");
92
+ return `${header}\n${divider}`;
93
+ };
94
+ exports.tableRowHeader = tableRowHeader;
95
+ const tableRowBody = (row) => {
96
+ return row.join("|");
97
+ };
98
+ exports.tableRowBody = tableRowBody;
99
+ const table = (cells) => {
100
+ const tableRows = cells.map((row, i) => !i ? (0, exports.tableRowHeader)(row) : (0, exports.tableRowBody)(row));
101
+ return tableRows.join("\n");
102
+ };
103
+ exports.table = table;
74
104
  //# sourceMappingURL=md.js.map