@@ -33,7 +33,7 @@ use crate::html::highlight;
33
33
use crate :: html:: toc:: TocBuilder ;
34
34
use crate :: test;
35
35
36
- use pulldown_cmark:: { html, CowStr , Event , Options , Parser , Tag } ;
36
+ use pulldown_cmark:: { html, CodeBlockKind , CowStr , Event , Options , Parser , Tag } ;
37
37
38
38
#[ cfg( test) ]
39
39
mod tests;
@@ -189,10 +189,15 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
189
189
let compile_fail;
190
190
let ignore;
191
191
let edition;
192
- if let Some ( Event :: Start ( Tag :: CodeBlock ( lang) ) ) = event {
193
- let parse_result = LangString :: parse ( & lang, self . check_error_codes , false ) ;
192
+ if let Some ( Event :: Start ( Tag :: CodeBlock ( kind) ) ) = event {
193
+ let parse_result = match kind {
194
+ CodeBlockKind :: Fenced ( ref lang) => {
195
+ LangString :: parse ( & lang, self . check_error_codes , false )
196
+ }
197
+ CodeBlockKind :: Indented => LangString :: all_false ( ) ,
198
+ } ;
194
199
if !parse_result. rust {
195
- return Some ( Event :: Start ( Tag :: CodeBlock ( lang ) ) ) ;
200
+ return Some ( Event :: Start ( Tag :: CodeBlock ( kind ) ) ) ;
196
201
}
197
202
compile_fail = parse_result. compile_fail ;
198
203
ignore = parse_result. ignore ;
@@ -370,11 +375,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a,
370
375
}
371
376
372
377
let event = self . inner . next ( ) ;
373
- if let Some ( Event :: Start ( Tag :: Header ( level) ) ) = event {
378
+ if let Some ( Event :: Start ( Tag :: Heading ( level) ) ) = event {
374
379
let mut id = String :: new ( ) ;
375
380
for event in & mut self . inner {
376
381
match & event {
377
- Event :: End ( Tag :: Header ( ..) ) => break ,
382
+ Event :: End ( Tag :: Heading ( ..) ) => break ,
378
383
Event :: Text ( text) | Event :: Code ( text) => {
379
384
id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
380
385
}
@@ -391,18 +396,18 @@ impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a,
391
396
let mut html_header = String :: new ( ) ;
392
397
html:: push_html ( & mut html_header, self . buf . iter ( ) . cloned ( ) ) ;
393
398
let sec = builder. push ( level as u32 , html_header, id. clone ( ) ) ;
394
- self . buf . push_front ( Event :: InlineHtml ( format ! ( "{} " , sec) . into ( ) ) ) ;
399
+ self . buf . push_front ( Event :: Html ( format ! ( "{} " , sec) . into ( ) ) ) ;
395
400
}
396
401
397
- self . buf . push_back ( Event :: InlineHtml ( format ! ( "</a></h{}>" , level) . into ( ) ) ) ;
402
+ self . buf . push_back ( Event :: Html ( format ! ( "</a></h{}>" , level) . into ( ) ) ) ;
398
403
399
404
let start_tags = format ! (
400
405
"<h{level} id=\" {id}\" class=\" section-header\" >\
401
406
<a href=\" #{id}\" >",
402
407
id = id,
403
408
level = level
404
409
) ;
405
- return Some ( Event :: InlineHtml ( start_tags. into ( ) ) ) ;
410
+ return Some ( Event :: Html ( start_tags. into ( ) ) ) ;
406
411
}
407
412
event
408
413
}
@@ -556,40 +561,44 @@ pub fn find_testable_code<T: test::Tester>(
556
561
error_codes : ErrorCodes ,
557
562
enable_per_target_ignores : bool ,
558
563
) {
559
- let mut parser = Parser :: new ( doc) ;
564
+ let mut parser = Parser :: new ( doc) . into_offset_iter ( ) ;
560
565
let mut prev_offset = 0 ;
561
566
let mut nb_lines = 0 ;
562
567
let mut register_header = None ;
563
- while let Some ( event) = parser. next ( ) {
568
+ while let Some ( ( event, offset ) ) = parser. next ( ) {
564
569
match event {
565
- Event :: Start ( Tag :: CodeBlock ( s) ) => {
566
- let offset = parser. get_offset ( ) ;
567
-
568
- let block_info = if s. is_empty ( ) {
569
- LangString :: all_false ( )
570
- } else {
571
- LangString :: parse ( & * s, error_codes, enable_per_target_ignores)
570
+ Event :: Start ( Tag :: CodeBlock ( kind) ) => {
571
+ let block_info = match kind {
572
+ CodeBlockKind :: Fenced ( ref lang) => {
573
+ if lang. is_empty ( ) {
574
+ LangString :: all_false ( )
575
+ } else {
576
+ LangString :: parse ( lang, error_codes, enable_per_target_ignores)
577
+ }
578
+ }
579
+ CodeBlockKind :: Indented => LangString :: all_false ( ) ,
572
580
} ;
573
581
if !block_info. rust {
574
582
continue ;
575
583
}
584
+
576
585
let mut test_s = String :: new ( ) ;
577
586
578
- while let Some ( Event :: Text ( s) ) = parser. next ( ) {
587
+ while let Some ( ( Event :: Text ( s) , _ ) ) = parser. next ( ) {
579
588
test_s. push_str ( & s) ;
580
589
}
581
-
582
590
let text = test_s
583
591
. lines ( )
584
592
. map ( |l| map_line ( l) . for_code ( ) )
585
593
. collect :: < Vec < Cow < ' _ , str > > > ( )
586
594
. join ( "\n " ) ;
587
- nb_lines += doc[ prev_offset..offset] . lines ( ) . count ( ) ;
588
- let line = tests. get_line ( ) + nb_lines;
595
+
596
+ nb_lines += doc[ prev_offset..offset. start ] . lines ( ) . count ( ) ;
597
+ let line = tests. get_line ( ) + nb_lines + 1 ;
589
598
tests. add_test ( text, block_info, line) ;
590
- prev_offset = offset;
599
+ prev_offset = offset. start ;
591
600
}
592
- Event :: Start ( Tag :: Header ( level) ) => {
601
+ Event :: Start ( Tag :: Heading ( level) ) => {
593
602
register_header = Some ( level as u32 ) ;
594
603
}
595
604
Event :: Text ( ref s) if register_header. is_some ( ) => {
@@ -783,7 +792,7 @@ impl MarkdownHtml<'_> {
783
792
784
793
// Treat inline HTML as plain text.
785
794
let p = p. map ( |event| match event {
786
- Event :: Html ( text) | Event :: InlineHtml ( text ) => Event :: Text ( text) ,
795
+ Event :: Html ( text) => Event :: Text ( text) ,
787
796
_ => event,
788
797
} ) ;
789
798
@@ -842,10 +851,10 @@ pub fn plain_summary_line(md: &str) -> String {
842
851
let next_event = next_event. unwrap ( ) ;
843
852
let ( ret, is_in) = match next_event {
844
853
Event :: Start ( Tag :: Paragraph ) => ( None , 1 ) ,
845
- Event :: Start ( Tag :: Header ( _) ) => ( None , 1 ) ,
854
+ Event :: Start ( Tag :: Heading ( _) ) => ( None , 1 ) ,
846
855
Event :: Code ( code) => ( Some ( format ! ( "`{}`" , code) ) , 0 ) ,
847
856
Event :: Text ( ref s) if self . is_in > 0 => ( Some ( s. as_ref ( ) . to_owned ( ) ) , 0 ) ,
848
- Event :: End ( Tag :: Paragraph ) | Event :: End ( Tag :: Header ( _) ) => ( None , -1 ) ,
857
+ Event :: End ( Tag :: Paragraph ) | Event :: End ( Tag :: Heading ( _) ) => ( None , -1 ) ,
849
858
_ => ( None , 0 ) ,
850
859
} ;
851
860
if is_in > 0 || ( is_in < 0 && self . is_in > 0 ) {
@@ -940,68 +949,79 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
940
949
return code_blocks;
941
950
}
942
951
943
- let mut p = Parser :: new_ext ( md, opts ( ) ) ;
944
-
945
- let mut code_block_start = 0 ;
946
- let mut code_start = 0 ;
947
- let mut is_fenced = false ;
948
- let mut previous_offset = 0 ;
949
- let mut in_rust_code_block = false ;
950
- while let Some ( event) = p. next ( ) {
951
- let offset = p. get_offset ( ) ;
952
+ let mut p = Parser :: new_ext ( md, opts ( ) ) . into_offset_iter ( ) ;
952
953
954
+ while let Some ( ( event, offset) ) = p. next ( ) {
953
955
match event {
954
956
Event :: Start ( Tag :: CodeBlock ( syntax) ) => {
955
- let lang_string = if syntax. is_empty ( ) {
956
- LangString :: all_false ( )
957
- } else {
958
- LangString :: parse ( & * syntax, ErrorCodes :: Yes , false )
959
- } ;
960
-
961
- if lang_string. rust {
962
- in_rust_code_block = true ;
963
-
964
- code_start = offset;
965
- code_block_start = match md[ previous_offset..offset] . find ( "```" ) {
966
- Some ( fence_idx) => {
967
- is_fenced = true ;
968
- previous_offset + fence_idx
957
+ let ( syntax, code_start, code_end, range, is_fenced) = match syntax {
958
+ CodeBlockKind :: Fenced ( syntax) => {
959
+ let syntax = syntax. as_ref ( ) ;
960
+ let lang_string = if syntax. is_empty ( ) {
961
+ LangString :: all_false ( )
962
+ } else {
963
+ LangString :: parse ( & * syntax, ErrorCodes :: Yes , false )
964
+ } ;
965
+ if !lang_string. rust {
966
+ continue ;
969
967
}
970
- None => {
971
- is_fenced = false ;
972
- offset
968
+ let syntax = if syntax. is_empty ( ) { None } else { Some ( syntax. to_owned ( ) ) } ;
969
+ let ( code_start, mut code_end) = match p. next ( ) {
970
+ Some ( ( Event :: Text ( _) , offset) ) => ( offset. start , offset. end ) ,
971
+ Some ( ( _, sub_offset) ) => {
972
+ let code = Range { start : sub_offset. start , end : sub_offset. start } ;
973
+ code_blocks. push ( RustCodeBlock {
974
+ is_fenced : true ,
975
+ range : offset,
976
+ code,
977
+ syntax,
978
+ } ) ;
979
+ continue ;
980
+ }
981
+ None => {
982
+ let code = Range { start : offset. end , end : offset. end } ;
983
+ code_blocks. push ( RustCodeBlock {
984
+ is_fenced : true ,
985
+ range : offset,
986
+ code,
987
+ syntax,
988
+ } ) ;
989
+ continue ;
990
+ }
991
+ } ;
992
+ while let Some ( ( Event :: Text ( _) , offset) ) = p. next ( ) {
993
+ code_end = offset. end ;
973
994
}
974
- } ;
975
- }
976
- }
977
- Event :: End ( Tag :: CodeBlock ( syntax) ) if in_rust_code_block => {
978
- in_rust_code_block = false ;
979
-
980
- let code_block_end = if is_fenced {
981
- let fence_str = & md[ previous_offset..offset] . chars ( ) . rev ( ) . collect :: < String > ( ) ;
982
- fence_str
983
- . find ( "```" )
984
- . map ( |fence_idx| offset - fence_idx)
985
- . unwrap_or_else ( || offset)
986
- } else if md. as_bytes ( ) . get ( offset) . map ( |b| * b == b'\n' ) . unwrap_or_default ( ) {
987
- offset - 1
988
- } else {
989
- offset
995
+ ( syntax, code_start, code_end, offset, true )
996
+ }
997
+ CodeBlockKind :: Indented => {
998
+ // The ending of the offset goes too far sometime so we reduce it by one in
999
+ // these cases.
1000
+ if offset. end > offset. start
1001
+ && md. get ( offset. end ..=offset. end ) == Some ( & "\n " )
1002
+ {
1003
+ (
1004
+ None ,
1005
+ offset. start ,
1006
+ offset. end ,
1007
+ Range { start : offset. start , end : offset. end - 1 } ,
1008
+ false ,
1009
+ )
1010
+ } else {
1011
+ ( None , offset. start , offset. end , offset, false )
1012
+ }
1013
+ }
990
1014
} ;
991
1015
992
- let code_end = if is_fenced { previous_offset } else { code_block_end } ;
993
-
994
1016
code_blocks. push ( RustCodeBlock {
995
1017
is_fenced,
996
- range : Range { start : code_block_start , end : code_block_end } ,
1018
+ range,
997
1019
code : Range { start : code_start, end : code_end } ,
998
- syntax : if !syntax . is_empty ( ) { Some ( syntax . into_string ( ) ) } else { None } ,
1020
+ syntax,
999
1021
} ) ;
1000
1022
}
1001
1023
_ => ( ) ,
1002
1024
}
1003
-
1004
- previous_offset = offset;
1005
1025
}
1006
1026
1007
1027
code_blocks
0 commit comments