@@ -52,9 +52,6 @@ impl Parser {
5252 }
5353
5454 fn next_node ( & mut self ) -> Result < Node , ParserError > {
55- if self . is_at_end ( ) {
56- return Err ( ParserError :: Ast ( AstError :: StreamError ( "AtEnd" . to_string ( ) ) ) ) ;
57- }
5855 let token = self . peek ( ) ?;
5956 match token. token_type ( ) {
6057 TokenType :: DjangoBlock ( content) => {
@@ -65,6 +62,10 @@ impl Parser {
6562 self . consume ( ) ?;
6663 self . parse_django_variable ( content)
6764 }
65+ TokenType :: Comment ( content, start, end) => {
66+ self . consume ( ) ?;
67+ self . parse_comment ( content, start, end. as_deref ( ) )
68+ }
6869 TokenType :: Text ( _)
6970 | TokenType :: Whitespace ( _)
7071 | TokenType :: Newline
@@ -74,10 +75,9 @@ impl Parser {
7475 | TokenType :: ScriptTagOpen ( _)
7576 | TokenType :: ScriptTagClose ( _)
7677 | TokenType :: StyleTagOpen ( _)
77- | TokenType :: StyleTagClose ( _) => self . parse_text ( ) ,
78- TokenType :: Comment ( content, start, end) => {
78+ | TokenType :: StyleTagClose ( _) => {
7979 self . consume ( ) ?;
80- self . parse_comment ( content , start , end . as_deref ( ) )
80+ self . parse_text ( )
8181 }
8282 TokenType :: Eof => Err ( ParserError :: Ast ( AstError :: StreamError ( "AtEnd" . to_string ( ) ) ) ) ,
8383 }
@@ -136,13 +136,16 @@ impl Parser {
136136 tag : branch_tag. clone ( ) ,
137137 nodes : branch_nodes. clone ( ) ,
138138 } ) ) ;
139- closing = Some ( Box :: new ( Block :: Closing { tag : next_tag. clone ( ) } ) ) ;
139+ closing = Some ( Box :: new ( Block :: Closing {
140+ tag : next_tag. clone ( ) ,
141+ } ) ) ;
140142 found_closing = true ;
141143 break ;
142144 }
143145 }
144146 // Check if this is another branch tag
145- if branches. iter ( ) . any ( |b| b. name == next_tag. name ) {
147+ if branches. iter ( ) . any ( |b| b. name == next_tag. name )
148+ {
146149 // Push the current branch and start a new one
147150 nodes. push ( Node :: Block ( Block :: Branch {
148151 tag : branch_tag. clone ( ) ,
@@ -164,7 +167,9 @@ impl Parser {
164167 nodes : branch_nodes. clone ( ) ,
165168 } ) ) ;
166169 // Add error for unclosed tag
167- self . errors . push ( ParserError :: Ast ( AstError :: UnclosedTag ( tag_name. clone ( ) ) ) ) ;
170+ self . errors . push ( ParserError :: Ast ( AstError :: UnclosedTag (
171+ tag_name. clone ( ) ,
172+ ) ) ) ;
168173 }
169174 if found_closing {
170175 break ;
@@ -198,9 +203,16 @@ impl Parser {
198203 } ;
199204
200205 // Add error if we didn't find a closing tag for a block
201- if let Block :: Block { closing : None , tag : tag_ref, .. } = & block {
206+ if let Block :: Block {
207+ closing : None ,
208+ tag : tag_ref,
209+ ..
210+ } = & block
211+ {
202212 if let Some ( expected_closing) = & spec. closing {
203- self . errors . push ( ParserError :: Ast ( AstError :: UnclosedTag ( tag_ref. name . clone ( ) ) ) ) ;
213+ self . errors . push ( ParserError :: Ast ( AstError :: UnclosedTag (
214+ tag_ref. name . clone ( ) ,
215+ ) ) ) ;
204216 }
205217 }
206218
@@ -246,58 +258,40 @@ impl Parser {
246258 }
247259
248260 fn parse_text ( & mut self ) -> Result < Node , ParserError > {
249- let start_token = self . peek ( ) ?;
261+ let start_token = self . peek_previous ( ) ?;
250262 let start_pos = start_token. start ( ) . unwrap_or ( 0 ) ;
251- let mut total_length = start_token. length ( ) . unwrap_or ( 0 ) ;
252263
253- // Handle newlines by returning next node
264+ // If we start with a newline, skip it
254265 if matches ! ( start_token. token_type( ) , TokenType :: Newline ) {
255- self . consume ( ) ?;
256- let node = self . next_node ( ) ?;
257- return Ok ( node) ;
258- }
259-
260- let mut content = match start_token. token_type ( ) {
261- TokenType :: Text ( text) => text. to_string ( ) ,
262- TokenType :: Whitespace ( count) => " " . repeat ( * count) ,
263- _ => {
264- return Err ( ParserError :: Ast ( AstError :: InvalidTag (
265- "Expected text or whitespace token" . to_string ( ) ,
266- ) ) )
267- }
268- } ;
269- self . consume ( ) ?;
270-
271- // Look ahead for more tokens until newline
272- while let Ok ( next_token) = self . peek ( ) {
273- match next_token. token_type ( ) {
274- TokenType :: Text ( text) => {
275- content. push_str ( text) ;
276- total_length += next_token. length ( ) . unwrap_or ( 0 ) ;
277- self . consume ( ) ?;
278- }
279- TokenType :: Whitespace ( count) => {
280- content. push_str ( & " " . repeat ( * count) ) ;
281- total_length += next_token. length ( ) . unwrap_or ( 0 ) ;
282- self . consume ( ) ?;
283- }
284- TokenType :: Newline => {
285- // Include newline in span but not content
286- total_length += next_token. length ( ) . unwrap_or ( 0 ) ;
266+ return self . next_node ( ) ;
267+ }
268+
269+ // Use TokenType's Display implementation for formatting
270+ let mut text = start_token. token_type ( ) . to_string ( ) ;
271+ let mut total_length: u32 = u32:: try_from ( text. len ( ) ) . unwrap ( ) ;
272+
273+ while let Ok ( token) = self . peek ( ) {
274+ match token. token_type ( ) {
275+ TokenType :: DjangoBlock ( _)
276+ | TokenType :: DjangoVariable ( _)
277+ | TokenType :: Comment ( _, _, _)
278+ | TokenType :: Newline
279+ | TokenType :: Eof => break ,
280+ _ => {
281+ let token_text = token. token_type ( ) . to_string ( ) ;
282+ text. push_str ( & token_text) ;
283+ total_length += u32:: try_from ( token_text. len ( ) ) . unwrap ( ) ;
287284 self . consume ( ) ?;
288- break ;
289285 }
290- _ => break ,
291286 }
292287 }
293288
294289 // Skip empty text nodes
295- if content. trim ( ) . is_empty ( ) {
296- let node = self . next_node ( ) ?;
297- Ok ( node)
290+ if text. trim ( ) . is_empty ( ) {
291+ self . next_node ( )
298292 } else {
299293 Ok ( Node :: Text {
300- content,
294+ content : text ,
301295 span : Span :: new ( start_pos, total_length) ,
302296 } )
303297 }
0 commit comments