1
1
import { Client } from "@notionhq/client" ;
2
2
import { ListBlockChildrenResponse } from "@notionhq/client/build/src/api-endpoints" ;
3
3
import { NotionToMarkdown } from "notion-to-md" ;
4
- import markdownTable from "markdown-table" ;
5
4
import {
6
5
ListBlockChildrenResponseResult ,
7
6
ListBlockChildrenResponseResults ,
8
7
} from "notion-to-md/build/types" ;
9
8
import { notionCalloutToAdmonition } from "./CalloutTransformer" ;
10
9
import { numberedListTransformer } from "./NumberedListTransformer" ;
10
+ import { notionColumnToMarkdown } from "./ColumnTransformer" ;
11
+ import { notionColumnListToMarkdown } from "./ColumnListTransformer" ;
12
+ import { tableTransformer } from "./TableTransformer" ;
13
+ import { headingTransformer } from "./HeadingTransformer" ;
11
14
12
15
export function setupCustomTransformers (
13
16
notionToMarkdown : NotionToMarkdown ,
@@ -25,66 +28,12 @@ export function setupCustomTransformers(
25
28
notionColumnToMarkdown ( notionToMarkdown , notionClient , block )
26
29
) ;
27
30
28
- // This is mostly a copy of the table handler from notion-to-md. The change is to handle newlines in the
29
- // notion cell content.
30
31
notionToMarkdown . setCustomTransformer (
31
32
"table" ,
32
- async ( block : ListBlockChildrenResponseResult ) => {
33
- const { id, has_children } = block as any ;
34
- const tableArr : string [ ] [ ] = [ ] ;
35
- if ( has_children ) {
36
- const tableRows = await getBlockChildren ( notionClient , id , 100 ) ;
37
- // console.log(">>", tableRows);
38
- const rowsPromise = tableRows ?. map ( async row => {
39
- const { type } = row as any ;
40
- const cells = ( row as any ) [ type ] [ "cells" ] ;
41
-
42
- /**
43
- * this is more like a hack since matching the type text was
44
- * difficult. So converting each cell to paragraph type to
45
- * reuse the blockToMarkdown function
46
- */
47
- const cellStringPromise = cells . map (
48
- async ( cell : any ) =>
49
- await notionToMarkdown . blockToMarkdown ( {
50
- type : "paragraph" ,
51
- paragraph : { rich_text : cell } ,
52
- } as ListBlockChildrenResponseResult )
53
- ) ;
54
-
55
- const cellStringArrRaw : string [ ] = await Promise . all (
56
- cellStringPromise
57
- ) ;
58
- // This is our patch to the original notion-to-md code.
59
- const cellStringArr = cellStringArrRaw . map ( c =>
60
- c
61
- // Trailing newlines are almost certainly not wanted, and converting to br's gives weird results
62
- . replace ( / [ \r \n ] + $ / , "" )
63
- // Preserving line breaks within cells can't be done in stock markdown. Since we're producing
64
- // mdx, which supports embedded HTML, we can handle it with <br/>.
65
- // I'm not sure exactly what line breaks might occur in the input, depending on platform,
66
- // so handle all the common cases.
67
- . replaceAll ( "\r\n" , "<br/>" )
68
- . replaceAll ( "\n" , "<br/>" )
69
- . replaceAll ( "\r" , "<br/>" )
70
- ) ;
71
- // console.log("~~", cellStringArr);
72
- tableArr . push ( cellStringArr ) ;
73
- // console.log(tableArr);
74
- } ) ;
75
- await Promise . all ( rowsPromise || [ ] ) ;
76
- }
77
- return markdownTable ( tableArr ) ;
78
- }
33
+ ( block : ListBlockChildrenResponseResult ) =>
34
+ tableTransformer ( notionToMarkdown , notionClient , block )
79
35
) ;
80
36
81
- // In Notion, you can make a callout and change its emoji. We map 5 of these
82
- // to the 5 Docusaurus admonition styles.
83
- // This is mostly a copy of the callout code from notion-to-md. The change is to output docusaurus
84
- // admonitions instead of emulating a callout with markdown > syntax.
85
- // Note: I haven't yet tested this with any emoji except "💡"/"tip", nor the case where the
86
- // callout has-children. Not even sure what that would mean, since the document I was testing
87
- // with has quite complex markup inside the callout, but still takes the no-children branch.
88
37
notionToMarkdown . setCustomTransformer (
89
38
"callout" ,
90
39
( block : ListBlockChildrenResponseResult ) =>
@@ -97,26 +46,8 @@ export function setupCustomTransformers(
97
46
numberedListTransformer ( notionToMarkdown , notionClient , block )
98
47
) ;
99
48
100
- const headingCustomTransformer = async (
101
- block : ListBlockChildrenResponseResult
102
- ) => {
103
- // This is the other half of the horrible hack in pull.ts which sets the type
104
- // of every heading_n to my_heading_n. We have to do this because if
105
- // we simply set a custom transformer to heading_n, it will keep
106
- // recursively calling this code, with blockToMarkdown using the custom transformer
107
- // over and over. Instead, we want blockToMarkdown to give us the normal
108
- // result, to which we will append the block ID to enable heading links.
109
- ( block as any ) . type = ( block as any ) . type . replace ( "my_" , "" ) ;
110
-
111
- const unmodifiedMarkdown = await notionToMarkdown . blockToMarkdown ( block ) ;
112
- // For some reason, inline links come in without the dashes, so we have to strip
113
- // dashes here to match them.
114
- const blockIdSansDashes = block . id . replaceAll ( "-" , "" ) ;
115
- // To make heading links work in docusaurus, you make them look like:
116
- // ### Hello World {#my-explicit-id}
117
- // See https://docusaurus.io/docs/markdown-features/toc#heading-ids.
118
- return `${ unmodifiedMarkdown } {#${ blockIdSansDashes } }` ;
119
- } ;
49
+ const headingCustomTransformer = ( block : ListBlockChildrenResponseResult ) =>
50
+ headingTransformer ( notionToMarkdown , notionClient , block ) ;
120
51
notionToMarkdown . setCustomTransformer (
121
52
"my_heading_1" ,
122
53
headingCustomTransformer
@@ -134,53 +65,6 @@ export function setupCustomTransformers(
134
65
// page so we don't do it here.
135
66
}
136
67
137
- async function notionColumnListToMarkdown (
138
- notionToMarkdown : NotionToMarkdown ,
139
- notionClient : Client ,
140
- block : ListBlockChildrenResponseResult
141
- ) : Promise < string > {
142
- // Enhance: The @notionhq /client, which uses the official API, cannot yet get at column formatting information (column_ratio)
143
- // However https://github1s.com/NotionX/react-notion-x/blob/master/packages/react-notion-x/src/block.tsx#L528 can get it.
144
-
145
- const { id, has_children } = block as any ; // "any" because the notion api type system is complex with a union that don't know how to help TS to cope with
146
-
147
- if ( ! has_children ) return "" ;
148
-
149
- const column_list_children = await getBlockChildren ( notionClient , id , 100 ) ;
150
-
151
- const column_list_promise = column_list_children . map (
152
- async column => await notionToMarkdown . blockToMarkdown ( column )
153
- ) ;
154
-
155
- const columns : string [ ] = await Promise . all ( column_list_promise ) ;
156
-
157
- return `<div class='notion-row'>\n${ columns . join ( "\n\n" ) } \n</div>` ;
158
- }
159
- async function notionColumnToMarkdown (
160
- notionToMarkdown : NotionToMarkdown ,
161
- notionClient : Client ,
162
- block : ListBlockChildrenResponseResult
163
- ) : Promise < string > {
164
- //console.log(JSON.stringify(block));
165
- const { id, has_children } = block as any ; // "any" because the notion api type system is complex with a union that don't know how to help TS to cope with
166
-
167
- if ( ! has_children ) return "" ;
168
-
169
- const children = await getBlockChildren ( notionClient , id , 100 ) ;
170
-
171
- const childrenPromise = children . map (
172
- async column => await notionToMarkdown . blockToMarkdown ( column )
173
- ) ;
174
-
175
- const childrenStrings : string [ ] = await Promise . all ( childrenPromise ) ;
176
-
177
- // note: it would look better in the markup with \n, but that
178
- // causes notion-to-md to give us ":::A" instead of \n for some reason.
179
- return `<div class='notion-column'>\n\n${ childrenStrings . join (
180
- "\n\n"
181
- ) } \n\n</div>`;
182
- }
183
-
184
68
export async function getBlockChildren (
185
69
notionClient : Client ,
186
70
block_id : string ,
0 commit comments