@@ -187,6 +187,56 @@ pub fn markdown_to_html(
187
187
188
188
{
189
189
let mut events = Vec :: new ( ) ;
190
+ macro_rules! render_shortcodes {
191
+ ( $is_text: expr, $text: expr, $range: expr) => {
192
+ let orig_range_start = $range. start;
193
+ loop {
194
+ if let Some ( ref shortcode) = next_shortcode {
195
+ if !$range. contains( & shortcode. span. start) {
196
+ break ;
197
+ }
198
+ let sc_span = shortcode. span. clone( ) ;
199
+
200
+ // we have some text before the shortcode, push that first
201
+ if $range. start != sc_span. start {
202
+ let content = $text[ ( $range. start - orig_range_start)
203
+ ..( sc_span. start - orig_range_start) ]
204
+ . to_string( )
205
+ . into( ) ;
206
+ events. push( if $is_text {
207
+ Event :: Text ( content)
208
+ } else {
209
+ Event :: Html ( content)
210
+ } ) ;
211
+ $range. start = sc_span. start;
212
+ }
213
+
214
+ // Now we should be at the same idx as the shortcode
215
+ let shortcode = next_shortcode. take( ) . unwrap( ) ;
216
+ match shortcode. render( & context. tera, & context. tera_context) {
217
+ Ok ( s) => {
218
+ events. push( Event :: Html ( s. into( ) ) ) ;
219
+ $range. start += SHORTCODE_PLACEHOLDER . len( ) ;
220
+ }
221
+ Err ( e) => {
222
+ error = Some ( e) ;
223
+ break ;
224
+ }
225
+ }
226
+ next_shortcode = html_shortcodes. pop( ) ;
227
+ continue ;
228
+ }
229
+
230
+ break ;
231
+ }
232
+
233
+ if !$range. is_empty( ) {
234
+ // The $range value is for the whole document, not for this slice of text
235
+ let content = $text[ ( $range. start - orig_range_start) ..] . to_string( ) . into( ) ;
236
+ events. push( if $is_text { Event :: Text ( content) } else { Event :: Html ( content) } ) ;
237
+ }
238
+ } ;
239
+ }
190
240
191
241
for ( event, mut range) in Parser :: new_ext ( content, opts) . into_offset_iter ( ) {
192
242
match event {
@@ -206,45 +256,7 @@ pub fn markdown_to_html(
206
256
continue ;
207
257
}
208
258
209
- // TODO: find a way to share that code with the HTML handler
210
- let mut new_text = text. clone ( ) ;
211
- loop {
212
- if let Some ( ref shortcode) = next_shortcode {
213
- let sc_span = shortcode. span . clone ( ) ;
214
- if range. contains ( & sc_span. start ) {
215
- if range. start != sc_span. start {
216
- events. push ( Event :: Text (
217
- new_text[ ..( sc_span. start - range. start ) ]
218
- . to_string ( )
219
- . into ( ) ,
220
- ) ) ;
221
- }
222
-
223
- let shortcode = next_shortcode. take ( ) . unwrap ( ) ;
224
-
225
- match shortcode. render ( & context. tera , & context. tera_context ) {
226
- Ok ( s) => {
227
- events. push ( Event :: Html ( s. into ( ) ) ) ;
228
- new_text = new_text[ ( sc_span. end - range. start ) ..]
229
- . to_owned ( )
230
- . into ( ) ;
231
- range. start = sc_span. end - range. start ;
232
- }
233
- Err ( e) => {
234
- error = Some ( e) ;
235
- break ;
236
- }
237
- }
238
-
239
- next_shortcode = html_shortcodes. pop ( ) ;
240
- continue ;
241
- }
242
- }
243
-
244
- break ;
245
- }
246
-
247
- events. push ( Event :: Text ( new_text[ ..] . to_string ( ) . into ( ) ) ) ;
259
+ render_shortcodes ! ( true , text, range) ;
248
260
}
249
261
}
250
262
Event :: Start ( Tag :: CodeBlock ( ref kind) ) => {
@@ -338,40 +350,7 @@ pub fn markdown_to_html(
338
350
continue ;
339
351
}
340
352
341
- let mut new_text = text. clone ( ) ;
342
- loop {
343
- if let Some ( ref shortcode) = next_shortcode {
344
- let sc_span = shortcode. span . clone ( ) ;
345
- if range. contains ( & sc_span. start ) {
346
- if range. start != sc_span. start {
347
- events. push ( Event :: Html (
348
- new_text[ ..( sc_span. start - range. start ) ] . to_owned ( ) . into ( ) ,
349
- ) ) ;
350
- }
351
-
352
- let shortcode = next_shortcode. take ( ) . unwrap ( ) ;
353
- match shortcode. render ( & context. tera , & context. tera_context ) {
354
- Ok ( s) => {
355
- events. push ( Event :: Html ( s. into ( ) ) ) ;
356
- new_text = new_text[ ( sc_span. end - range. start ) ..]
357
- . to_owned ( )
358
- . into ( ) ;
359
- range. start = sc_span. end - range. start ;
360
- }
361
- Err ( e) => {
362
- error = Some ( e) ;
363
- break ;
364
- }
365
- }
366
-
367
- next_shortcode = html_shortcodes. pop ( ) ;
368
- continue ;
369
- }
370
- }
371
-
372
- break ;
373
- }
374
- events. push ( Event :: Html ( new_text[ ..] . to_string ( ) . into ( ) ) ) ;
353
+ render_shortcodes ! ( false , text, range) ;
375
354
}
376
355
_ => events. push ( event) ,
377
356
}
0 commit comments