@@ -16,6 +16,8 @@ import {
1616import * as md from "./utils/md" ;
1717import { getBlockChildren } from "./utils/notion" ;
1818
19+ type LinkTransformer = ( text : string , href : string ) => Promise < string > ;
20+
1921/**
2022 * Converts a Notion page to Markdown.
2123 */
@@ -37,13 +39,21 @@ export class NotionToMarkdown {
3739
3840 setCustomTransformer (
3941 type : BlockType ,
40- transformer : CustomTransformer ,
42+ transformer : CustomTransformer
4143 ) : NotionToMarkdown {
4244 this . customTransformers [ type ] = transformer ;
4345
4446 return this ;
4547 }
4648
49+ setLinkTransformer ( fn : LinkTransformer ) {
50+ this . linkTransformer = fn ;
51+ }
52+
53+ async linkTransformer ( text : string , href : string ) {
54+ return md . link ( text , href ) ;
55+ }
56+
4757 /**
4858 * Converts Markdown Blocks to string
4959 * @param {MdBlock[] } mdBlocks - Array of markdown blocks
@@ -53,7 +63,7 @@ export class NotionToMarkdown {
5363 toMarkdownString (
5464 mdBlocks : MdBlock [ ] = [ ] ,
5565 pageIdentifier : string = "parent" ,
56- nestingLevel : number = 0 ,
66+ nestingLevel : number = 0
5767 ) : MdStringObject {
5868 let mdOutput : MdStringObject = { } ;
5969
@@ -80,15 +90,15 @@ export class NotionToMarkdown {
8090 // add extra line breaks non list blocks
8191 mdOutput [ pageIdentifier ] += `\n${ md . addTabSpace (
8292 mdBlocks . parent ,
83- nestingLevel ,
93+ nestingLevel
8494 ) } \n\n`;
8595 } else {
8696 // initialize if key doesn't exist
8797 mdOutput [ pageIdentifier ] = mdOutput [ pageIdentifier ] || "" ;
8898
8999 mdOutput [ pageIdentifier ] += `${ md . addTabSpace (
90100 mdBlocks . parent ,
91- nestingLevel ,
101+ nestingLevel
92102 ) } \n`;
93103 }
94104 }
@@ -120,26 +130,27 @@ export class NotionToMarkdown {
120130 mdOutput [ pageIdentifier ] = mdOutput [ pageIdentifier ] || "" ;
121131 if ( mdstr [ childPageTitle ] ) {
122132 // child page heading followed by child page content
123- mdOutput [ pageIdentifier ] +=
124- `\n${ childPageTitle } \n${ mdstr [ childPageTitle ] } ` ;
133+ mdOutput [
134+ pageIdentifier
135+ ] += `\n${ childPageTitle } \n${ mdstr [ childPageTitle ] } ` ;
125136 }
126137 }
127138 } else if ( mdBlocks . type === "toggle" ) {
128139 // convert children md object to md string
129140 const toggle_children_md_string = this . toMarkdownString (
130- mdBlocks . children ,
141+ mdBlocks . children
131142 ) ;
132143
133144 mdOutput [ pageIdentifier ] = mdOutput [ pageIdentifier ] || "" ;
134145 mdOutput [ pageIdentifier ] += md . toggle (
135146 mdBlocks . parent ,
136- toggle_children_md_string [ "parent" ] ,
147+ toggle_children_md_string [ "parent" ]
137148 ) ;
138149 } else if ( mdBlocks . type === "quote" ) {
139150 let mdstr = this . toMarkdownString (
140151 mdBlocks . children ,
141152 pageIdentifier ,
142- nestingLevel ,
153+ nestingLevel
143154 ) ;
144155
145156 const formattedContent = ( mdstr . parent ?? mdstr [ pageIdentifier ] )
@@ -159,12 +170,11 @@ export class NotionToMarkdown {
159170 mdOutput [ pageIdentifier ] += "\n" ;
160171 } else if ( mdBlocks . type === "callout" ) {
161172 // do nothing the callout block is already processed
162- }
163- else {
173+ } else {
164174 let mdstr = this . toMarkdownString (
165175 mdBlocks . children ,
166176 pageIdentifier ,
167- nestingLevel + 1 ,
177+ nestingLevel + 1
168178 ) ;
169179
170180 mdOutput [ pageIdentifier ] = mdOutput [ pageIdentifier ] || "" ;
@@ -188,11 +198,11 @@ export class NotionToMarkdown {
188198 */
189199 async pageToMarkdown (
190200 id : string ,
191- totalPage : number | null = null ,
201+ totalPage : number | null = null
192202 ) : Promise < MdBlock [ ] > {
193203 if ( ! this . notionClient ) {
194204 throw new Error (
195- "notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md" ,
205+ "notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md"
196206 ) ;
197207 }
198208 const blocks = await getBlockChildren ( this . notionClient , id , totalPage ) ;
@@ -212,11 +222,11 @@ export class NotionToMarkdown {
212222 async blocksToMarkdown (
213223 blocks ?: ListBlockChildrenResponseResults ,
214224 totalPage : number | null = null ,
215- mdBlocks : MdBlock [ ] = [ ] ,
225+ mdBlocks : MdBlock [ ] = [ ]
216226 ) : Promise < MdBlock [ ] > {
217227 if ( ! this . notionClient ) {
218228 throw new Error (
219- "notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md" ,
229+ "notion client is not provided, for more details check out https://github.com/souvikinator/notion-to-md"
220230 ) ;
221231 }
222232
@@ -244,7 +254,7 @@ export class NotionToMarkdown {
244254 let child_blocks = await getBlockChildren (
245255 this . notionClient ,
246256 block_id ,
247- totalPage ,
257+ totalPage
248258 ) ;
249259
250260 // Push this block to mdBlocks.
@@ -265,7 +275,7 @@ export class NotionToMarkdown {
265275 await this . blocksToMarkdown (
266276 child_blocks ,
267277 totalPage ,
268- mdBlocks [ l - 1 ] . children ,
278+ mdBlocks [ l - 1 ] . children
269279 ) ;
270280 }
271281
@@ -289,7 +299,9 @@ export class NotionToMarkdown {
289299 * @param {ListBlockChildrenResponseResult } block - single notion block
290300 * @returns {string } corresponding markdown string of the passed block
291301 */
292- async blockToMarkdown ( block : ListBlockChildrenResponseResult ) {
302+ async blockToMarkdown (
303+ block : ListBlockChildrenResponseResult
304+ ) : Promise < string > {
293305 if ( typeof block !== "object" || ! ( "type" in block ) ) return "" ;
294306
295307 let parsedData = "" ;
@@ -332,7 +344,7 @@ export class NotionToMarkdown {
332344 return await md . image (
333345 image_title ,
334346 link ,
335- this . config . convertImagesToBase64 ,
347+ this . config . convertImagesToBase64
336348 ) ;
337349 }
338350 break ;
@@ -370,12 +382,12 @@ export class NotionToMarkdown {
370382 title = caption ;
371383 } else if ( link ) {
372384 const matches = link . match (
373- / [ ^ \/ \\ & \? ] + \. \w { 3 , 4 } (? = ( [ \? & ] .* $ | $ ) ) / ,
385+ / [ ^ \/ \\ & \? ] + \. \w { 3 , 4 } (? = ( [ \? & ] .* $ | $ ) ) /
374386 ) ;
375387 title = matches ? matches [ 0 ] : type ;
376388 }
377389
378- return md . link ( title , link ) ;
390+ return await this . linkTransformer ( title , link ) ;
379391 }
380392 }
381393 break ;
@@ -399,7 +411,8 @@ export class NotionToMarkdown {
399411 } ;
400412 }
401413
402- if ( blockContent ) return md . link ( title , blockContent . url ) ;
414+ if ( blockContent )
415+ return await this . linkTransformer ( title , blockContent . url ) ;
403416 }
404417 break ;
405418
@@ -430,7 +443,7 @@ export class NotionToMarkdown {
430443 const tableRows = await getBlockChildren ( this . notionClient , id , 100 ) ;
431444 let rowsPromise = tableRows ?. map ( async ( row ) => {
432445 const { type } = row as any ;
433- if ( type !== ' table_row' ) return
446+ if ( type !== " table_row" ) return ;
434447 const cells = ( row as any ) . table_row [ "cells" ] ;
435448
436449 /**
@@ -443,7 +456,7 @@ export class NotionToMarkdown {
443456 await this . blockToMarkdown ( {
444457 type : "paragraph" ,
445458 paragraph : { rich_text : cell } ,
446- } as ListBlockChildrenResponseResult ) ,
459+ } as ListBlockChildrenResponseResult )
447460 ) ;
448461
449462 const cellStringArr = await Promise . all ( cellStringPromise ) ;
@@ -478,10 +491,10 @@ export class NotionToMarkdown {
478491 // In this case typescript is not able to index the types properly, hence ignoring the error
479492 // @ts -ignore
480493 let blockContent = block [ type ] . text || block [ type ] . rich_text || [ ] ;
481- blockContent . map ( ( content : Text | Equation ) => {
494+
495+ for ( const content of blockContent ) {
482496 if ( content . type === "equation" ) {
483497 parsedData += md . inlineEquation ( content . equation . expression ) ;
484- return ;
485498 }
486499
487500 const annotations = content . annotations ;
@@ -490,19 +503,24 @@ export class NotionToMarkdown {
490503 plain_text = this . annotatePlainText ( plain_text , annotations ) ;
491504
492505 if ( content [ "href" ] )
493- plain_text = md . link ( plain_text , content [ "href" ] ) ;
506+ plain_text = await this . linkTransformer (
507+ plain_text ,
508+ content [ "href" ]
509+ ) ;
494510
495511 parsedData += plain_text ;
496- } ) ;
512+ }
497513 }
498514 }
499515
500516 switch ( type ) {
501517 case "code" :
502518 {
503- const codeContent = block . code . rich_text . map ( ( t : any ) => t . plain_text ) . join ( "\n" ) ;
504- const language = block . code . language || "plaintext" ;
505- parsedData = md . codeBlock ( codeContent , language ) ;
519+ const codeContent = block . code . rich_text
520+ . map ( ( t : any ) => t . plain_text )
521+ . join ( "\n" ) ;
522+ const language = block . code . language || "plaintext" ;
523+ parsedData = md . codeBlock ( codeContent , language ) ;
506524 }
507525 break ;
508526
@@ -542,12 +560,12 @@ export class NotionToMarkdown {
542560 const callout_children_object = await getBlockChildren (
543561 this . notionClient ,
544562 id ,
545- 100 ,
563+ 100
546564 ) ;
547565
548566 // // parse children blocks to md object
549567 const callout_children = await this . blocksToMarkdown (
550- callout_children_object ,
568+ callout_children_object
551569 ) ;
552570
553571 callout_string += `${ parsedData } \n` ;
0 commit comments