@@ -892,6 +892,75 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> {
892892 extra. error_invalid_codeblock_attr ( err) ;
893893 }
894894 }
895+
896+ /// Returns false if the string is unfinished.
897+ fn skip_string ( & mut self ) -> bool {
898+ while let Some ( ( _, c) ) = self . inner . next ( ) {
899+ if c == '"' {
900+ return true ;
901+ }
902+ }
903+ self . emit_error ( "unclosed quote string: missing `\" ` at the end" ) ;
904+ false
905+ }
906+
907+ fn parse_in_attribute_block ( & mut self , start : usize ) -> Option < TokenKind < ' a > > {
908+ while let Some ( ( pos, c) ) = self . inner . next ( ) {
909+ if is_separator ( c) {
910+ return Some ( TokenKind :: Attribute ( & self . data [ start..pos] ) ) ;
911+ } else if c == '{' {
912+ // There shouldn't be a nested block!
913+ self . emit_error ( "unexpected `{` inside attribute block (`{}`)" ) ;
914+ let attr = & self . data [ start..pos] ;
915+ if attr. is_empty ( ) {
916+ return self . next ( ) ;
917+ }
918+ self . inner . next ( ) ;
919+ return Some ( TokenKind :: Attribute ( attr) ) ;
920+ } else if c == '}' {
921+ self . is_in_attribute_block = false ;
922+ let attr = & self . data [ start..pos] ;
923+ if attr. is_empty ( ) {
924+ return self . next ( ) ;
925+ }
926+ return Some ( TokenKind :: Attribute ( attr) ) ;
927+ } else if c == '"' && !self . skip_string ( ) {
928+ return None ;
929+ }
930+ }
931+ // Unclosed attribute block!
932+ self . emit_error ( "unclosed attribute block (`{}`): missing `}` at the end" ) ;
933+ let token = & self . data [ start..] ;
934+ if token. is_empty ( ) { None } else { Some ( TokenKind :: Attribute ( token) ) }
935+ }
936+
937+ fn parse_outside_attribute_block ( & mut self , start : usize ) -> Option < TokenKind < ' a > > {
938+ while let Some ( ( pos, c) ) = self . inner . next ( ) {
939+ if is_separator ( c) {
940+ return Some ( TokenKind :: Token ( & self . data [ start..pos] ) ) ;
941+ } else if c == '{' {
942+ self . is_in_attribute_block = true ;
943+ let token = & self . data [ start..pos] ;
944+ if token. is_empty ( ) {
945+ return self . next ( ) ;
946+ }
947+ return Some ( TokenKind :: Token ( token) ) ;
948+ } else if c == '}' {
949+ // We're not in a block so it shouldn't be there!
950+ self . emit_error ( "unexpected `}` outside attribute block (`{}`)" ) ;
951+ let token = & self . data [ start..pos] ;
952+ if token. is_empty ( ) {
953+ return self . next ( ) ;
954+ }
955+ self . inner . next ( ) ;
956+ return Some ( TokenKind :: Attribute ( token) ) ;
957+ } else if c == '"' && !self . skip_string ( ) {
958+ return None ;
959+ }
960+ }
961+ let token = & self . data [ start..] ;
962+ if token. is_empty ( ) { None } else { Some ( TokenKind :: Token ( token) ) }
963+ }
895964}
896965
897966impl < ' a , ' tcx > Iterator for TagIterator < ' a , ' tcx > {
@@ -905,55 +974,9 @@ impl<'a, 'tcx> Iterator for TagIterator<'a, 'tcx> {
905974 return None ;
906975 } ;
907976 if self . is_in_attribute_block {
908- while let Some ( ( pos, c) ) = self . inner . next ( ) {
909- if is_separator ( c) {
910- return Some ( TokenKind :: Attribute ( & self . data [ start..pos] ) ) ;
911- } else if c == '{' {
912- // There shouldn't be a nested block!
913- self . emit_error ( "unexpected `{` inside attribute block (`{}`)" ) ;
914- let attr = & self . data [ start..pos] ;
915- if attr. is_empty ( ) {
916- return self . next ( ) ;
917- }
918- self . inner . next ( ) ;
919- return Some ( TokenKind :: Attribute ( attr) ) ;
920- } else if c == '}' {
921- self . is_in_attribute_block = false ;
922- let attr = & self . data [ start..pos] ;
923- if attr. is_empty ( ) {
924- return self . next ( ) ;
925- }
926- return Some ( TokenKind :: Attribute ( attr) ) ;
927- }
928- }
929- // Unclosed attribute block!
930- self . emit_error ( "unclosed attribute block (`{}`): missing `}` at the end" ) ;
931- let token = & self . data [ start..] ;
932- if token. is_empty ( ) { None } else { Some ( TokenKind :: Attribute ( token) ) }
977+ self . parse_in_attribute_block ( start)
933978 } else {
934- while let Some ( ( pos, c) ) = self . inner . next ( ) {
935- if is_separator ( c) {
936- return Some ( TokenKind :: Token ( & self . data [ start..pos] ) ) ;
937- } else if c == '{' {
938- self . is_in_attribute_block = true ;
939- let token = & self . data [ start..pos] ;
940- if token. is_empty ( ) {
941- return self . next ( ) ;
942- }
943- return Some ( TokenKind :: Token ( token) ) ;
944- } else if c == '}' {
945- // We're not in a block so it shouldn't be there!
946- self . emit_error ( "unexpected `}` outside attribute block (`{}`)" ) ;
947- let token = & self . data [ start..pos] ;
948- if token. is_empty ( ) {
949- return self . next ( ) ;
950- }
951- self . inner . next ( ) ;
952- return Some ( TokenKind :: Attribute ( token) ) ;
953- }
954- }
955- let token = & self . data [ start..] ;
956- if token. is_empty ( ) { None } else { Some ( TokenKind :: Token ( token) ) }
979+ self . parse_outside_attribute_block ( start)
957980 }
958981 }
959982}
@@ -982,7 +1005,7 @@ fn handle_class(class: &str, after: &str, data: &mut LangString, extra: Option<&
9821005 extra. error_invalid_codeblock_attr ( & format ! ( "missing class name after `{after}`" ) ) ;
9831006 }
9841007 } else {
985- data. added_classes . push ( class. to_owned ( ) ) ;
1008+ data. added_classes . push ( class. replace ( '"' , "" ) ) ;
9861009 }
9871010}
9881011
0 commit comments