@@ -33,7 +33,7 @@ use crate::html::highlight;
3333use crate :: html:: toc:: TocBuilder ;
3434use crate :: test;
3535
36- use pulldown_cmark:: { html, CowStr , Event , Options , Parser , Tag } ;
36+ use pulldown_cmark:: { html, CodeBlockKind , CowStr , Event , Options , Parser , Tag } ;
3737
3838#[ cfg( test) ]
3939mod tests;
@@ -189,10 +189,15 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
189189 let compile_fail;
190190 let ignore;
191191 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+ } ;
194199 if !parse_result. rust {
195- return Some ( Event :: Start ( Tag :: CodeBlock ( lang ) ) ) ;
200+ return Some ( Event :: Start ( Tag :: CodeBlock ( kind ) ) ) ;
196201 }
197202 compile_fail = parse_result. compile_fail ;
198203 ignore = parse_result. ignore ;
@@ -370,11 +375,11 @@ impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a,
370375 }
371376
372377 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 {
374379 let mut id = String :: new ( ) ;
375380 for event in & mut self . inner {
376381 match & event {
377- Event :: End ( Tag :: Header ( ..) ) => break ,
382+ Event :: End ( Tag :: Heading ( ..) ) => break ,
378383 Event :: Text ( text) | Event :: Code ( text) => {
379384 id. extend ( text. chars ( ) . filter_map ( slugify) ) ;
380385 }
@@ -391,18 +396,18 @@ impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a,
391396 let mut html_header = String :: new ( ) ;
392397 html:: push_html ( & mut html_header, self . buf . iter ( ) . cloned ( ) ) ;
393398 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 ( ) ) ) ;
395400 }
396401
397- self . buf . push_back ( Event :: InlineHtml ( format ! ( "</a></h{}>" , level) . into ( ) ) ) ;
402+ self . buf . push_back ( Event :: Html ( format ! ( "</a></h{}>" , level) . into ( ) ) ) ;
398403
399404 let start_tags = format ! (
400405 "<h{level} id=\" {id}\" class=\" section-header\" >\
401406 <a href=\" #{id}\" >",
402407 id = id,
403408 level = level
404409 ) ;
405- return Some ( Event :: InlineHtml ( start_tags. into ( ) ) ) ;
410+ return Some ( Event :: Html ( start_tags. into ( ) ) ) ;
406411 }
407412 event
408413 }
@@ -556,40 +561,44 @@ pub fn find_testable_code<T: test::Tester>(
556561 error_codes : ErrorCodes ,
557562 enable_per_target_ignores : bool ,
558563) {
559- let mut parser = Parser :: new ( doc) ;
564+ let mut parser = Parser :: new ( doc) . into_offset_iter ( ) ;
560565 let mut prev_offset = 0 ;
561566 let mut nb_lines = 0 ;
562567 let mut register_header = None ;
563- while let Some ( event) = parser. next ( ) {
568+ while let Some ( ( event, offset ) ) = parser. next ( ) {
564569 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 ( ) ,
572580 } ;
573581 if !block_info. rust {
574582 continue ;
575583 }
584+
576585 let mut test_s = String :: new ( ) ;
577586
578- while let Some ( Event :: Text ( s) ) = parser. next ( ) {
587+ while let Some ( ( Event :: Text ( s) , _ ) ) = parser. next ( ) {
579588 test_s. push_str ( & s) ;
580589 }
581-
582590 let text = test_s
583591 . lines ( )
584592 . map ( |l| map_line ( l) . for_code ( ) )
585593 . collect :: < Vec < Cow < ' _ , str > > > ( )
586594 . 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 ;
589598 tests. add_test ( text, block_info, line) ;
590- prev_offset = offset;
599+ prev_offset = offset. start ;
591600 }
592- Event :: Start ( Tag :: Header ( level) ) => {
601+ Event :: Start ( Tag :: Heading ( level) ) => {
593602 register_header = Some ( level as u32 ) ;
594603 }
595604 Event :: Text ( ref s) if register_header. is_some ( ) => {
@@ -783,7 +792,7 @@ impl MarkdownHtml<'_> {
783792
784793 // Treat inline HTML as plain text.
785794 let p = p. map ( |event| match event {
786- Event :: Html ( text) | Event :: InlineHtml ( text ) => Event :: Text ( text) ,
795+ Event :: Html ( text) => Event :: Text ( text) ,
787796 _ => event,
788797 } ) ;
789798
@@ -842,10 +851,10 @@ pub fn plain_summary_line(md: &str) -> String {
842851 let next_event = next_event. unwrap ( ) ;
843852 let ( ret, is_in) = match next_event {
844853 Event :: Start ( Tag :: Paragraph ) => ( None , 1 ) ,
845- Event :: Start ( Tag :: Header ( _) ) => ( None , 1 ) ,
854+ Event :: Start ( Tag :: Heading ( _) ) => ( None , 1 ) ,
846855 Event :: Code ( code) => ( Some ( format ! ( "`{}`" , code) ) , 0 ) ,
847856 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 ) ,
849858 _ => ( None , 0 ) ,
850859 } ;
851860 if is_in > 0 || ( is_in < 0 && self . is_in > 0 ) {
@@ -940,68 +949,79 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
940949 return code_blocks;
941950 }
942951
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 ( ) ;
952953
954+ while let Some ( ( event, offset) ) = p. next ( ) {
953955 match event {
954956 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 ;
969967 }
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 ;
973994 }
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+ }
9901014 } ;
9911015
992- let code_end = if is_fenced { previous_offset } else { code_block_end } ;
993-
9941016 code_blocks. push ( RustCodeBlock {
9951017 is_fenced,
996- range : Range { start : code_block_start , end : code_block_end } ,
1018+ range,
9971019 code : Range { start : code_start, end : code_end } ,
998- syntax : if !syntax . is_empty ( ) { Some ( syntax . into_string ( ) ) } else { None } ,
1020+ syntax,
9991021 } ) ;
10001022 }
10011023 _ => ( ) ,
10021024 }
1003-
1004- previous_offset = offset;
10051025 }
10061026
10071027 code_blocks
0 commit comments