@@ -76,10 +76,145 @@ export function setupCustomTransformers(
76
76
}
77
77
) ;
78
78
79
+ // types copied from notion-to-md to allow compilation of copied code.
80
+ type TextRequest = string ;
81
+
82
+ type Annotations = {
83
+ bold : boolean ;
84
+ italic : boolean ;
85
+ strikethrough : boolean ;
86
+ underline : boolean ;
87
+ code : boolean ;
88
+ color :
89
+ | "default"
90
+ | "gray"
91
+ | "brown"
92
+ | "orange"
93
+ | "yellow"
94
+ | "green"
95
+ | "blue"
96
+ | "purple"
97
+ | "pink"
98
+ | "red"
99
+ | "gray_background"
100
+ | "brown_background"
101
+ | "orange_background"
102
+ | "yellow_background"
103
+ | "green_background"
104
+ | "blue_background"
105
+ | "purple_background"
106
+ | "pink_background"
107
+ | "red_background" ;
108
+ } ;
109
+ type Text = {
110
+ type : "text" ;
111
+ text : {
112
+ content : string ;
113
+ link : {
114
+ url : TextRequest ;
115
+ } | null ;
116
+ } ;
117
+ annotations : Annotations ;
118
+ plain_text : string ;
119
+ href : string | null ;
120
+ } ;
121
+
122
+ // In Notion, you can make a callout and change its emoji. We map 5 of these
123
+ // to the 5 Docusaurus admonition styles.
124
+ // This is mostly a copy of the callout code from notion-to-md. The change is to output docusaurus
125
+ // admonitions instead of emulating a callout with markdown > syntax.
126
+ // Note: I haven't yet tested this with any emoji except "💡"/"tip", nor the case where the
127
+ // callout has-children. Not even sure what that would mean, since the document I was testing
128
+ // with has quite complex markup inside the callout, but still takes the no-children branch.
129
+ notionToMarkdown . setCustomTransformer (
130
+ "callout" ,
131
+ async ( block : ListBlockChildrenResponseResult ) => {
132
+ // In this case typescript is not able to index the types properly, hence ignoring the error
133
+ // @ts -ignore
134
+ const blockContent = block . callout . text || block . callout . rich_text || [ ] ;
135
+ // @ts -ignore
136
+ const icon = block . callout . icon ;
137
+ let parsedData = "" ;
138
+ blockContent . map ( ( content : Text ) => {
139
+ const annotations = content . annotations ;
140
+ let plain_text = content . plain_text ;
141
+
142
+ plain_text = notionToMarkdown . annotatePlainText (
143
+ plain_text ,
144
+ annotations
145
+ ) ;
146
+
147
+ // if (content["href"])
148
+ // plain_text = md.link(plain_text, content["href"]);
149
+
150
+ parsedData += plain_text ;
151
+ } ) ;
152
+
153
+ let callout_string = "" ;
154
+ const { id, has_children } = block as any ;
155
+ if ( ! has_children ) {
156
+ const result1 = callout ( parsedData , icon ) ;
157
+ return result1 ;
158
+ }
159
+
160
+ const callout_children_object = await getBlockChildren (
161
+ notionClient ,
162
+ id ,
163
+ 100
164
+ ) ;
165
+
166
+ // // parse children blocks to md object
167
+ const callout_children = await notionToMarkdown . blocksToMarkdown (
168
+ callout_children_object
169
+ ) ;
170
+
171
+ callout_string += `${ parsedData } \n` ;
172
+ callout_children . map ( child => {
173
+ callout_string += `${ child . parent } \n\n` ;
174
+ } ) ;
175
+
176
+ const result = callout ( callout_string . trim ( ) , icon ) ;
177
+ return result ;
178
+ }
179
+ ) ;
180
+
79
181
// Note: Pull.ts also adds an image transformer, but has to do that for each
80
182
// page so we don't do it here.
81
183
}
82
184
185
+ const calloutsToAdmonitions = {
186
+ /* prettier-ignore */ "ℹ️" : "note" ,
187
+ "💡" : "tip" ,
188
+ "❗" : "info" ,
189
+ "⚠️" : "caution" ,
190
+ "🔥" : "danger" ,
191
+ } ;
192
+
193
+ // This is the main change from the notion-to-md code.
194
+ function callout ( text : string , icon ?: CalloutIcon ) {
195
+ let emoji : string | undefined ;
196
+ if ( icon ?. type === "emoji" ) {
197
+ emoji = icon . emoji ;
198
+ }
199
+ let docusaurusAdmonition = "note" ;
200
+ if ( emoji ) {
201
+ // the keyof typeof magic persuades typescript that it really is OK to use emoji as a key into calloutsToAdmonitions
202
+ docusaurusAdmonition =
203
+ calloutsToAdmonitions [ emoji as keyof typeof calloutsToAdmonitions ] ??
204
+ // For Notion callouts with other emojis, pass them through using hte emoji as the name.
205
+ // For this to work on a Docusaurus site, it will need to define that time on the remark-admonitions options in the docusaurus.config.js.
206
+ // See https://github.com/elviswolcott/remark-admonitions and https://docusaurus.io/docs/using-plugins#using-presets.
207
+ emoji ;
208
+ }
209
+ return `:::${ docusaurusAdmonition } \n\n${ text } \n\n:::\n\n` ;
210
+ }
211
+
212
+ type CalloutIcon =
213
+ | { type : "emoji" ; emoji ?: string }
214
+ | { type : "external" ; external ?: { url : string } }
215
+ | { type : "file" ; file : { url : string ; expiry_time : string } }
216
+ | null ;
217
+
83
218
async function notionColumnListToMarkdown (
84
219
notionToMarkdown : NotionToMarkdown ,
85
220
notionClient : Client ,
0 commit comments