@@ -160,19 +160,30 @@ function traverseMdastNode(node, delta, attributes = {}) {
160
160
}
161
161
break ;
162
162
163
- case "paragraph" :
163
+ case "paragraph" : {
164
164
for ( const child of node . children || [ ] ) {
165
165
traverseMdastNode ( child , delta , attributes ) ;
166
166
}
167
- delta . ops . push ( { insert : "\n" } ) ;
167
+ const pLineAttributes = { } ;
168
+ if ( attributes . blockquote ) {
169
+ pLineAttributes . blockquote = true ;
170
+ }
171
+ delta . ops . push ( { insert : "\n" , attributes : pLineAttributes } ) ;
168
172
break ;
173
+ }
169
174
170
- case "heading" :
175
+ case "heading" : {
176
+ const headingContentAttributes = { ...attributes , header : node . depth } ;
171
177
for ( const child of node . children || [ ] ) {
172
- traverseMdastNode ( child , delta , { header : node . depth } ) ;
178
+ traverseMdastNode ( child , delta , headingContentAttributes ) ;
179
+ }
180
+ const headingLineAttributes = { header : node . depth } ;
181
+ if ( attributes . blockquote ) {
182
+ headingLineAttributes . blockquote = true ;
173
183
}
174
- delta . ops . push ( { insert : "\n" , attributes : { header : node . depth } } ) ;
184
+ delta . ops . push ( { insert : "\n" , attributes : headingLineAttributes } ) ;
175
185
break ;
186
+ }
176
187
177
188
case "text" :
178
189
delta . ops . push ( { insert : node . value || "" , attributes } ) ;
@@ -212,36 +223,53 @@ function traverseMdastNode(node, delta, attributes = {}) {
212
223
}
213
224
break ;
214
225
215
- case "listItem" :
226
+ case "listItem" : {
227
+ const { list, ...listItemChildrenAttributes } = attributes ;
228
+
216
229
for ( const child of node . children || [ ] ) {
217
- traverseMdastNode ( child , delta , { } ) ;
230
+ traverseMdastNode ( child , delta , listItemChildrenAttributes ) ;
218
231
}
232
+
233
+ // Attributes for the listItem's newline (e.g., { list: 'bullet', blockquote: true })
234
+ // are in `attributes` passed to this `listItem` case.
219
235
{
220
236
const lastOp = delta . ops [ delta . ops . length - 1 ] ;
221
- if ( lastOp && lastOp . insert === "\n" ) lastOp . attributes = attributes ;
222
- else delta . ops . push ( { insert : "\n" , attributes } ) ;
237
+ if ( lastOp && lastOp . insert === "\n" ) {
238
+ lastOp . attributes = { ...lastOp . attributes , ...attributes } ;
239
+ } else {
240
+ delta . ops . push ( { insert : "\n" , attributes } ) ;
241
+ }
223
242
}
224
243
break ;
244
+ }
225
245
226
246
case "blockquote" :
227
247
for ( const child of node . children || [ ] ) {
228
248
traverseMdastNode ( child , delta , { ...attributes , blockquote : true } ) ;
229
249
}
230
250
break ;
231
251
232
- case "code" :
233
- delta . ops . push ( {
234
- insert : node . value || "" ,
235
- attributes : { "code-block" : node . lang || "plain" } ,
236
- } ) ;
237
- delta . ops . push ( {
238
- insert : "\n" ,
239
- attributes : { "code-block" : node . lang || "plain" } ,
240
- } ) ;
252
+ case "code" : { // mdast 'code' is a block
253
+ const codeBlockLineFormat = { "code-block" : node . lang || true } ;
254
+ if ( attributes . blockquote ) {
255
+ codeBlockLineFormat . blockquote = true ;
256
+ }
257
+
258
+ const textInCodeAttributes = { } ;
259
+ if ( attributes . blockquote ) { // Text lines also get blockquote if active
260
+ textInCodeAttributes . blockquote = true ;
261
+ }
262
+
263
+ const lines = ( node . value || "" ) . split ( '\n' ) ;
264
+ for ( const lineText of lines ) {
265
+ delta . ops . push ( { insert : lineText , attributes : textInCodeAttributes } ) ;
266
+ delta . ops . push ( { insert : "\n" , attributes : codeBlockLineFormat } ) ;
267
+ }
241
268
break ;
269
+ }
242
270
243
271
case "inlineCode" :
244
- delta . ops . push ( { insert : node . value || "" , attributes : { code : true } } ) ;
272
+ delta . ops . push ( { insert : node . value || "" , attributes : { ... attributes , code : true } } ) ;
245
273
break ;
246
274
247
275
default :
0 commit comments