@@ -105,17 +105,20 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
105
105
} ) ;
106
106
107
107
macro_rules! event_loop_break {
108
- ( $parser: expr, $toc_builder: expr, $shorter: expr, $buf: expr, $( $end_event: pat) |* ) => { {
109
- event_loop_break( $parser, $toc_builder, $shorter, $buf, false , $( $end_event: pat) |* ) ;
110
- } } ;
111
- ( $parser: expr, $toc_builder: expr, $shorter: expr, $buf: expr, $escape: expr,
108
+ ( $parser: expr, $toc_builder: expr, $shorter: expr, $buf: expr, $escape: expr, $id: expr,
112
109
$( $end_event: pat) |* ) => { {
110
+ fn inner( id: & mut Option <& mut String >, s: & str ) {
111
+ if let Some ( ref mut id) = * id {
112
+ id. push_str( s) ;
113
+ }
114
+ }
113
115
while let Some ( event) = $parser. next( ) {
114
116
match event {
115
117
$( $end_event) |* => break ,
116
118
Event :: Text ( ref s) => {
119
+ inner( $id, s) ;
117
120
if $escape {
118
- $buf. push_str( & escape ( s ) ) ;
121
+ $buf. push_str( & format! ( "{}" , Escape ( s ) ) ) ;
119
122
} else {
120
123
$buf. push_str( s) ;
121
124
}
@@ -124,7 +127,7 @@ macro_rules! event_loop_break {
124
127
$buf. push( ' ' ) ;
125
128
}
126
129
x => {
127
- looper( $parser, & mut $buf, Some ( x) , $toc_builder, $shorter) ;
130
+ looper( $parser, & mut $buf, Some ( x) , $toc_builder, $shorter, $id ) ;
128
131
}
129
132
}
130
133
}
@@ -135,13 +138,6 @@ pub fn render(w: &mut fmt::Formatter,
135
138
s : & str ,
136
139
print_toc : bool ,
137
140
shorter : MarkdownOutputStyle ) -> fmt:: Result {
138
- fn escape ( entry : & str ) -> String {
139
- entry. replace ( "<" , "<" )
140
- . replace ( "'" , "'" )
141
- . replace ( ">" , ">" )
142
- . replace ( "&" , "&" )
143
- }
144
-
145
141
fn block ( parser : & mut Parser , buffer : & mut String , lang : & str ) {
146
142
let mut origtext = String :: new ( ) ;
147
143
while let Some ( event) = parser. next ( ) {
@@ -223,10 +219,11 @@ pub fn render(w: &mut fmt::Formatter,
223
219
fn header ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
224
220
shorter : MarkdownOutputStyle , level : i32 ) {
225
221
let mut ret = String :: new ( ) ;
226
- event_loop_break ! ( parser, toc_builder, shorter, ret, true , Event :: End ( Tag :: Header ( _) ) ) ;
222
+ let mut id = String :: new ( ) ;
223
+ event_loop_break ! ( parser, toc_builder, shorter, ret, true , & mut Some ( & mut id) ,
224
+ Event :: End ( Tag :: Header ( _) ) ) ;
227
225
ret = ret. trim_right ( ) . to_owned ( ) ;
228
226
229
- let id = ret. clone ( ) ;
230
227
let id = id. chars ( ) . filter_map ( |c| {
231
228
if c. is_alphanumeric ( ) || c == '-' || c == '_' {
232
229
if c. is_ascii ( ) {
@@ -254,30 +251,33 @@ pub fn render(w: &mut fmt::Formatter,
254
251
}
255
252
256
253
fn codespan ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
257
- shorter : MarkdownOutputStyle ) {
254
+ shorter : MarkdownOutputStyle , id : & mut Option < & mut String > ) {
258
255
let mut content = String :: new ( ) ;
259
- event_loop_break ! ( parser, toc_builder, shorter, content, true , Event :: End ( Tag :: Code ) ) ;
256
+ event_loop_break ! ( parser, toc_builder, shorter, content, false , id , Event :: End ( Tag :: Code ) ) ;
260
257
buffer. push_str ( & format ! ( "<code>{}</code>" ,
261
258
Escape ( & collapse_whitespace( content. trim_right( ) ) ) ) ) ;
262
259
}
263
260
264
261
fn link ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
265
- shorter : MarkdownOutputStyle , url : & str , mut title : String ) {
266
- event_loop_break ! ( parser, toc_builder, shorter, title, true , Event :: End ( Tag :: Link ( _, _) ) ) ;
262
+ shorter : MarkdownOutputStyle , url : & str , mut title : String ,
263
+ id : & mut Option < & mut String > ) {
264
+ event_loop_break ! ( parser, toc_builder, shorter, title, true , id,
265
+ Event :: End ( Tag :: Link ( _, _) ) ) ;
267
266
buffer. push_str ( & format ! ( "<a href=\" {}\" >{}</a>" , url, title) ) ;
268
267
}
269
268
270
269
fn paragraph ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
271
- shorter : MarkdownOutputStyle ) {
270
+ shorter : MarkdownOutputStyle , id : & mut Option < & mut String > ) {
272
271
let mut content = String :: new ( ) ;
273
- event_loop_break ! ( parser, toc_builder, shorter, content, true , Event :: End ( Tag :: Paragraph ) ) ;
272
+ event_loop_break ! ( parser, toc_builder, shorter, content, true , id,
273
+ Event :: End ( Tag :: Paragraph ) ) ;
274
274
buffer. push_str ( & format ! ( "<p>{}</p>" , content. trim_right( ) ) ) ;
275
275
}
276
276
277
277
fn cell ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
278
278
shorter : MarkdownOutputStyle ) {
279
279
let mut content = String :: new ( ) ;
280
- event_loop_break ! ( parser, toc_builder, shorter, content, true ,
280
+ event_loop_break ! ( parser, toc_builder, shorter, content, true , & mut None ,
281
281
Event :: End ( Tag :: TableHead ) |
282
282
Event :: End ( Tag :: Table ( _) ) |
283
283
Event :: End ( Tag :: TableRow ) |
@@ -297,7 +297,7 @@ pub fn render(w: &mut fmt::Formatter,
297
297
cell ( parser, & mut content, toc_builder, shorter) ;
298
298
}
299
299
x => {
300
- looper ( parser, & mut content, Some ( x) , toc_builder, shorter) ;
300
+ looper ( parser, & mut content, Some ( x) , toc_builder, shorter, & mut None ) ;
301
301
}
302
302
}
303
303
}
@@ -314,7 +314,7 @@ pub fn render(w: &mut fmt::Formatter,
314
314
cell ( parser, & mut content, toc_builder, shorter) ;
315
315
}
316
316
x => {
317
- looper ( parser, & mut content, Some ( x) , toc_builder, shorter) ;
317
+ looper ( parser, & mut content, Some ( x) , toc_builder, shorter, & mut None ) ;
318
318
}
319
319
}
320
320
}
@@ -351,7 +351,8 @@ pub fn render(w: &mut fmt::Formatter,
351
351
fn blockquote ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
352
352
shorter : MarkdownOutputStyle ) {
353
353
let mut content = String :: new ( ) ;
354
- event_loop_break ! ( parser, toc_builder, shorter, content, true , Event :: End ( Tag :: BlockQuote ) ) ;
354
+ event_loop_break ! ( parser, toc_builder, shorter, content, true , & mut None ,
355
+ Event :: End ( Tag :: BlockQuote ) ) ;
355
356
buffer. push_str ( & format ! ( "<blockquote>{}</blockquote>" , content. trim_right( ) ) ) ;
356
357
}
357
358
@@ -362,10 +363,10 @@ pub fn render(w: &mut fmt::Formatter,
362
363
match event {
363
364
Event :: End ( Tag :: Item ) => break ,
364
365
Event :: Text ( ref s) => {
365
- content. push_str ( & escape ( s ) ) ;
366
+ content. push_str ( & format ! ( "{}" , Escape ( s ) ) ) ;
366
367
}
367
368
x => {
368
- looper ( parser, & mut content, Some ( x) , toc_builder, shorter) ;
369
+ looper ( parser, & mut content, Some ( x) , toc_builder, shorter, & mut None ) ;
369
370
}
370
371
}
371
372
}
@@ -382,29 +383,32 @@ pub fn render(w: &mut fmt::Formatter,
382
383
list_item ( parser, & mut content, toc_builder, shorter) ;
383
384
}
384
385
x => {
385
- looper ( parser, & mut content, Some ( x) , toc_builder, shorter) ;
386
+ looper ( parser, & mut content, Some ( x) , toc_builder, shorter, & mut None ) ;
386
387
}
387
388
}
388
389
}
389
390
buffer. push_str ( & format ! ( "<ul>{}</ul>" , content) ) ;
390
391
}
391
392
392
393
fn emphasis ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
393
- shorter : MarkdownOutputStyle ) {
394
+ shorter : MarkdownOutputStyle , id : & mut Option < & mut String > ) {
394
395
let mut content = String :: new ( ) ;
395
- event_loop_break ! ( parser, toc_builder, shorter, content, true , Event :: End ( Tag :: Emphasis ) ) ;
396
+ event_loop_break ! ( parser, toc_builder, shorter, content, false , id,
397
+ Event :: End ( Tag :: Emphasis ) ) ;
396
398
buffer. push_str ( & format ! ( "<em>{}</em>" , content) ) ;
397
399
}
398
400
399
401
fn strong ( parser : & mut Parser , buffer : & mut String , toc_builder : & mut Option < TocBuilder > ,
400
- shorter : MarkdownOutputStyle ) {
402
+ shorter : MarkdownOutputStyle , id : & mut Option < & mut String > ) {
401
403
let mut content = String :: new ( ) ;
402
- event_loop_break ! ( parser, toc_builder, shorter, content, true , Event :: End ( Tag :: Strong ) ) ;
404
+ event_loop_break ! ( parser, toc_builder, shorter, content, false , id,
405
+ Event :: End ( Tag :: Strong ) ) ;
403
406
buffer. push_str ( & format ! ( "<strong>{}</strong>" , content) ) ;
404
407
}
405
408
406
409
fn looper < ' a > ( parser : & ' a mut Parser , buffer : & mut String , next_event : Option < Event < ' a > > ,
407
- toc_builder : & mut Option < TocBuilder > , shorter : MarkdownOutputStyle ) -> bool {
410
+ toc_builder : & mut Option < TocBuilder > , shorter : MarkdownOutputStyle ,
411
+ id : & mut Option < & mut String > ) -> bool {
408
412
if let Some ( event) = next_event {
409
413
match event {
410
414
Event :: Start ( Tag :: CodeBlock ( lang) ) => {
@@ -414,13 +418,13 @@ pub fn render(w: &mut fmt::Formatter,
414
418
header ( parser, buffer, toc_builder, shorter, level) ;
415
419
}
416
420
Event :: Start ( Tag :: Code ) => {
417
- codespan ( parser, buffer, toc_builder, shorter) ;
421
+ codespan ( parser, buffer, toc_builder, shorter, id ) ;
418
422
}
419
423
Event :: Start ( Tag :: Paragraph ) => {
420
- paragraph ( parser, buffer, toc_builder, shorter) ;
424
+ paragraph ( parser, buffer, toc_builder, shorter, id ) ;
421
425
}
422
426
Event :: Start ( Tag :: Link ( ref url, ref t) ) => {
423
- link ( parser, buffer, toc_builder, shorter, url, t. as_ref ( ) . to_owned ( ) ) ;
427
+ link ( parser, buffer, toc_builder, shorter, url, t. as_ref ( ) . to_owned ( ) , id ) ;
424
428
}
425
429
Event :: Start ( Tag :: Table ( _) ) => {
426
430
table ( parser, buffer, toc_builder, shorter) ;
@@ -432,10 +436,10 @@ pub fn render(w: &mut fmt::Formatter,
432
436
list ( parser, buffer, toc_builder, shorter) ;
433
437
}
434
438
Event :: Start ( Tag :: Emphasis ) => {
435
- emphasis ( parser, buffer, toc_builder, shorter) ;
439
+ emphasis ( parser, buffer, toc_builder, shorter, id ) ;
436
440
}
437
441
Event :: Start ( Tag :: Strong ) => {
438
- strong ( parser, buffer, toc_builder, shorter) ;
442
+ strong ( parser, buffer, toc_builder, shorter, id ) ;
439
443
}
440
444
Event :: Html ( h) | Event :: InlineHtml ( h) => {
441
445
buffer. push_str ( & * h) ;
@@ -457,7 +461,7 @@ pub fn render(w: &mut fmt::Formatter,
457
461
let mut parser = Parser :: new_ext ( s, pulldown_cmark:: OPTION_ENABLE_TABLES ) ;
458
462
loop {
459
463
let next_event = parser. next ( ) ;
460
- if !looper ( & mut parser, & mut buffer, next_event, & mut toc_builder, shorter) {
464
+ if !looper ( & mut parser, & mut buffer, next_event, & mut toc_builder, shorter, & mut None ) {
461
465
break
462
466
}
463
467
}
@@ -742,7 +746,7 @@ mod tests {
742
746
fn test_header ( ) {
743
747
fn t ( input : & str , expect : & str ) {
744
748
let output = format ! ( "{}" , Markdown ( input, MarkdownOutputStyle :: Fancy ) ) ;
745
- assert_eq ! ( output, expect) ;
749
+ assert_eq ! ( output, expect, "original: {}" , input ) ;
746
750
reset_ids ( true ) ;
747
751
}
748
752
@@ -751,10 +755,10 @@ mod tests {
751
755
t ( "## Foo-bar_baz qux" , "<h2 id=\" foo-bar_baz-qux\" class=\" section-\
752
756
header\" ><a href=\" #foo-bar_baz-qux\" >Foo-bar_baz qux</a></h2>") ;
753
757
t ( "### **Foo** *bar* baz!?!& -_qux_-%" ,
754
- "<h3 id=\" foo-bar-baz--_qux_ -\" class=\" section-header\" >\
755
- <a href=\" #foo-bar-baz--_qux_ -\" ><strong>Foo</strong> \
756
- <em>bar</em> baz!?!& -_qux_ -%</a></h3>") ;
757
- t ( "####**Foo?** & \\ *bar?!* _`baz`_ ❤ #qux" ,
758
+ "<h3 id=\" foo-bar-baz--qux -\" class=\" section-header\" >\
759
+ <a href=\" #foo-bar-baz--qux -\" ><strong>Foo</strong> \
760
+ <em>bar</em> baz!?!& -<em>qux</em> -%</a></h3>") ;
761
+ t ( "#### **Foo?** & \\ *bar?!* _`baz`_ ❤ #qux" ,
758
762
"<h4 id=\" foo--bar--baz--qux\" class=\" section-header\" >\
759
763
<a href=\" #foo--bar--baz--qux\" ><strong>Foo?</strong> & *bar?!* \
760
764
<em><code>baz</code></em> ❤ #qux</a></h4>") ;
@@ -764,7 +768,7 @@ mod tests {
764
768
fn test_header_ids_multiple_blocks ( ) {
765
769
fn t ( input : & str , expect : & str ) {
766
770
let output = format ! ( "{}" , Markdown ( input, MarkdownOutputStyle :: Fancy ) ) ;
767
- assert_eq ! ( output, expect) ;
771
+ assert_eq ! ( output, expect, "original: {}" , input ) ;
768
772
}
769
773
770
774
let test = || {
@@ -790,7 +794,7 @@ mod tests {
790
794
fn test_plain_summary_line ( ) {
791
795
fn t ( input : & str , expect : & str ) {
792
796
let output = plain_summary_line ( input) ;
793
- assert_eq ! ( output, expect) ;
797
+ assert_eq ! ( output, expect, "original: {}" , input ) ;
794
798
}
795
799
796
800
t ( "hello [Rust](https://www.rust-lang.org) :)" , "hello Rust :)" ) ;
@@ -804,7 +808,7 @@ mod tests {
804
808
fn test_markdown_html_escape ( ) {
805
809
fn t ( input : & str , expect : & str ) {
806
810
let output = format ! ( "{}" , MarkdownHtml ( input) ) ;
807
- assert_eq ! ( output, expect) ;
811
+ assert_eq ! ( output, expect, "original: {}" , input ) ;
808
812
}
809
813
810
814
t ( "`Struct<'a, T>`" , "<p><code>Struct<'a, T></code></p>" ) ;
0 commit comments