@@ -56,6 +56,7 @@ pub fn parse_document<'a>(arena: &'a Arena<'a>, md: &str, options: &Options) ->
5656
5757pub struct Parser < ' a , ' o , ' c > {
5858 arena : & ' a Arena < ' a > ,
59+ options : & ' o Options < ' c > ,
5960 refmap : RefMap ,
6061 footnote_defs : inlines:: FootnoteDefs < ' a > ,
6162 root : Node < ' a > ,
@@ -73,7 +74,6 @@ pub struct Parser<'a, 'o, 'c> {
7374 curline_end_col : usize ,
7475 last_line_length : usize ,
7576 total_size : usize ,
76- options : & ' o Options < ' c > ,
7777}
7878
7979/// A reference link's resolved details.
@@ -100,6 +100,7 @@ where
100100 fn new ( arena : & ' a Arena < ' a > , root : Node < ' a > , options : & ' o Options < ' c > ) -> Self {
101101 Parser {
102102 arena,
103+ options,
103104 refmap : RefMap :: new ( ) ,
104105 footnote_defs : inlines:: FootnoteDefs :: new ( ) ,
105106 root,
@@ -117,7 +118,6 @@ where
117118 curline_end_col : 0 ,
118119 last_line_length : 0 ,
119120 total_size : 0 ,
120- options,
121121 }
122122 }
123123
@@ -371,17 +371,24 @@ where
371371 }
372372
373373 self . indent = self . first_nonspace_column - self . column ;
374- self . blank = self . first_nonspace < line. len ( )
375- && strings:: is_line_end_char ( bytes[ self . first_nonspace ] ) ;
374+ self . blank = bytes
375+ . get ( self . first_nonspace )
376+ . map_or ( true , |& b| strings:: is_line_end_char ( b) ) ;
376377 }
377378
378379 fn parse_block_quote_prefix ( & mut self , line : & str ) -> bool {
379380 let bytes = line. as_bytes ( ) ;
380381 let indent = self . indent ;
381- if indent <= 3 && bytes[ self . first_nonspace ] == b'>' && self . is_not_greentext ( line) {
382+ if indent <= 3
383+ && bytes. get ( self . first_nonspace ) == Some ( & b'>' )
384+ && self . is_not_greentext ( line)
385+ {
382386 self . advance_offset ( line, indent + 1 , true ) ;
383387
384- if strings:: is_space_or_tab ( bytes[ self . offset ] ) {
388+ if bytes
389+ . get ( self . offset )
390+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
391+ {
385392 self . advance_offset ( line, 1 , true ) ;
386393 }
387394
@@ -393,7 +400,10 @@ where
393400
394401 fn is_not_greentext ( & self , line : & str ) -> bool {
395402 !self . options . extension . greentext
396- || strings:: is_space_or_tab ( line. as_bytes ( ) [ self . first_nonspace + 1 ] )
403+ || line
404+ . as_bytes ( )
405+ . get ( self . first_nonspace + 1 )
406+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
397407 }
398408
399409 fn parse_node_item_prefix ( & mut self , line : & str , container : Node < ' a > , nl : & NodeList ) -> bool {
@@ -456,7 +466,7 @@ where
456466 }
457467
458468 let bytes = line. as_bytes ( ) ;
459- let matched = if self . indent <= 3 && bytes[ self . first_nonspace ] == fence_char {
469+ let matched = if self . indent <= 3 && bytes. get ( self . first_nonspace ) == Some ( & fence_char) {
460470 scanners:: close_code_fence ( & line[ self . first_nonspace ..] ) . unwrap_or ( 0 )
461471 } else {
462472 0
@@ -472,7 +482,11 @@ where
472482 }
473483
474484 let mut i = fence_offset;
475- while i > 0 && strings:: is_space_or_tab ( bytes[ self . offset ] ) {
485+ while i > 0
486+ && bytes
487+ . get ( self . offset )
488+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
489+ {
476490 self . advance_offset ( line, 1 , true ) ;
477491 i -= 1 ;
478492 }
@@ -515,7 +529,7 @@ where
515529 } ;
516530
517531 let bytes = line. as_bytes ( ) ;
518- let matched = if self . indent <= 3 && bytes[ self . first_nonspace ] == b'>' {
532+ let matched = if self . indent <= 3 && bytes. get ( self . first_nonspace ) == Some ( & b'>' ) {
519533 scanners:: close_multiline_block_quote_fence ( & line[ self . first_nonspace ..] ) . unwrap_or ( 0 )
520534 } else {
521535 0
@@ -540,7 +554,11 @@ where
540554 }
541555
542556 let mut i = fence_offset;
543- while i > 0 && strings:: is_space_or_tab ( bytes[ self . offset ] ) {
557+ while i > 0
558+ && bytes
559+ . get ( self . offset )
560+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
561+ {
544562 self . advance_offset ( line, 1 , true ) ;
545563 i -= 1 ;
546564 }
@@ -586,14 +604,16 @@ where
586604 }
587605 }
588606
589- // Compute a candidate end position for the container by looking
590- // at its deepest-last descendant. Return it only if it has a
591- // non-zero column; the caller can fall back to the container's
592- // start position if desired.
593- if let Some ( mut last_desc) = container. last_child ( ) {
594- while let Some ( ld) = last_desc. last_child ( ) {
595- last_desc = ld;
596- }
607+ // Compute a candidate end position for the container by looking at
608+ // its last child. Return it only if it has a non-zero column; the
609+ // caller can fall back to the container's start position if desired.
610+ //
611+ // We originally looked at the deepest-last descendant, but there
612+ // may be intermediate containers that are larger than it, which we
613+ // should use instead. If looking just at the last child isn't
614+ // enough in some circumstances, we should consider using the widest
615+ // of the last descendants.
616+ if let Some ( last_desc) = container. last_child ( ) {
597617 let last_end = last_desc. data ( ) . sourcepos . end ;
598618 if last_end. column != 0 {
599619 return Some ( last_end) ;
@@ -695,7 +715,8 @@ where
695715 }
696716
697717 fn detect_alert ( & self , line : & str ) -> Option < AlertType > {
698- if self . options . extension . alerts && line. as_bytes ( ) [ self . first_nonspace ] == b'>' {
718+ if self . options . extension . alerts && line. as_bytes ( ) . get ( self . first_nonspace ) == Some ( & b'>' )
719+ {
699720 scanners:: alert_start ( & line[ self . first_nonspace ..] )
700721 } else {
701722 None
@@ -1033,7 +1054,11 @@ where
10331054
10341055 let offset = self . first_nonspace + matched - self . offset ;
10351056 self . advance_offset ( line, offset, false ) ;
1036- if strings:: is_space_or_tab ( line. as_bytes ( ) [ self . offset ] ) {
1057+ if line
1058+ . as_bytes ( )
1059+ . get ( self . offset )
1060+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
1061+ {
10371062 self . advance_offset ( line, 1 , true ) ;
10381063 }
10391064
@@ -1172,12 +1197,20 @@ where
11721197 ( self . partially_consumed_tab , self . offset , self . column ) ;
11731198
11741199 let bytes = line. as_bytes ( ) ;
1175- while self . column - save_column <= 5 && strings:: is_space_or_tab ( bytes[ self . offset ] ) {
1200+ while self . column - save_column <= 5
1201+ && bytes
1202+ . get ( self . offset )
1203+ . map_or ( false , |& b| strings:: is_space_or_tab ( b) )
1204+ {
11761205 self . advance_offset ( line, 1 , true ) ;
11771206 }
11781207
11791208 let i = self . column - save_column;
1180- if !( 1 ..5 ) . contains ( & i) || strings:: is_line_end_char ( bytes[ self . offset ] ) {
1209+ if !( 1 ..5 ) . contains ( & i)
1210+ || bytes
1211+ . get ( self . offset )
1212+ . map_or ( false , |& b| strings:: is_line_end_char ( b) )
1213+ {
11811214 nl. padding = matched + 1 ;
11821215 self . offset = save_offset;
11831216 self . column = save_column;
@@ -1559,8 +1592,11 @@ where
15591592 _ => false ,
15601593 } {
15611594 ast. sourcepos . end = ( self . line_number , self . curline_end_col ) . into ( ) ;
1562- } else if matches ! ( ast. value, NodeValue :: ThematicBreak ) {
1563- // sourcepos.end set during opening.
1595+ } else if matches ! (
1596+ ast. value,
1597+ NodeValue :: ThematicBreak | NodeValue :: TableRow ( ..) | NodeValue :: Table ( ..)
1598+ ) {
1599+ // sourcepos.end set by itself or managed below.
15641600 } else {
15651601 ast. sourcepos . end = ( self . line_number - 1 , self . last_line_length ) . into ( ) ;
15661602 }
@@ -1630,7 +1666,7 @@ where
16301666 }
16311667 nl. tight = self . determine_list_tight ( node) ;
16321668 }
1633- NodeValue :: FootnoteDefinition ( _) => {
1669+ NodeValue :: Table ( .. ) | NodeValue :: FootnoteDefinition ( _) => {
16341670 if let Some ( candidate_end) = self . fix_zero_end_columns ( node) {
16351671 ast. sourcepos . end = candidate_end;
16361672 }
@@ -2134,6 +2170,9 @@ fn parse_list_marker(
21342170 let mut i = pos;
21352171 while strings:: is_space_or_tab ( bytes[ i] ) {
21362172 i += 1 ;
2173+ if i == bytes. len ( ) {
2174+ return None ;
2175+ }
21372176 }
21382177 if strings:: is_line_end_char ( bytes[ i] ) {
21392178 return None ;
0 commit comments