diff --git a/crates/djls-template-ast/src/parser.rs b/crates/djls-template-ast/src/parser.rs index be50fb7..18ce7dd 100644 --- a/crates/djls-template-ast/src/parser.rs +++ b/crates/djls-template-ast/src/parser.rs @@ -54,6 +54,11 @@ impl Parser { fn next_node(&mut self) -> Result { let token = self.peek()?; match token.token_type() { + TokenType::Comment(content, start, end) => { + self.consume()?; + self.parse_comment(content, start, end.as_deref()) + } + TokenType::Eof => Err(ParserError::Ast(AstError::StreamError("AtEnd".to_string()))), TokenType::DjangoBlock(content) => { self.consume()?; self.parse_django_block(content) @@ -62,24 +67,39 @@ impl Parser { self.consume()?; self.parse_django_variable(content) } - TokenType::Comment(content, start, end) => { - self.consume()?; - self.parse_comment(content, start, end.as_deref()) - } - TokenType::Text(_) - | TokenType::Whitespace(_) - | TokenType::Newline + TokenType::HtmlTagClose(_) | TokenType::HtmlTagOpen(_) - | TokenType::HtmlTagClose(_) | TokenType::HtmlTagVoid(_) - | TokenType::ScriptTagOpen(_) + | TokenType::Newline | TokenType::ScriptTagClose(_) + | TokenType::ScriptTagOpen(_) + | TokenType::StyleTagClose(_) | TokenType::StyleTagOpen(_) - | TokenType::StyleTagClose(_) => { + | TokenType::Text(_) + | TokenType::Whitespace(_) => { self.consume()?; self.parse_text() } - TokenType::Eof => Err(ParserError::Ast(AstError::StreamError("AtEnd".to_string()))), + } + } + + fn parse_comment( + &mut self, + content: &str, + start: &str, + end: Option<&str>, + ) -> Result { + let token = self.peek_previous()?; + let start_pos = token.start().unwrap_or(0); + + // Only treat Django comments as Comment nodes + if start == "{#" && end == Some("#}") { + Ok(Node::Comment { + content: content.to_string(), + span: Span::new(start_pos, token.token_type().len().unwrap_or(0) as u32), + }) + } else { + self.parse_text() } } @@ -209,7 +229,7 @@ impl Parser { .. } = &block { - if let Some(expected_closing) = &spec.closing { + if let Some(_expected_closing) = &spec.closing { self.errors.push(ParserError::Ast(AstError::UnclosedTag( tag_ref.name.clone(), ))); @@ -245,7 +265,7 @@ impl Parser { filters.push(DjangoFilter { name: filter_name.to_string(), args: filter_args, - span: Span::new(start + 4, content.len() as u32), // Account for {{ and space + span: Span::new(start + 4, content.len() as u32), }); } } @@ -253,7 +273,7 @@ impl Parser { Ok(Node::Variable { bits, filters, - span: Span::new(start + 3, content.len() as u32), // Account for {{ and space + span: Span::new(start + 3, content.len() as u32), }) } @@ -261,8 +281,16 @@ impl Parser { let start_token = self.peek_previous()?; let start_pos = start_token.start().unwrap_or(0); - if matches!(start_token.token_type(), TokenType::Newline) { - return self.next_node(); + match start_token.token_type() { + TokenType::Newline => return self.next_node(), + TokenType::Whitespace(_) + if self + .peek_at(-2) + .map_or(false, |t| matches!(t.token_type(), TokenType::Newline)) => + { + return self.next_node() + } + _ => {} } let mut text = start_token.token_type().to_string(); @@ -294,26 +322,6 @@ impl Parser { } } - fn parse_comment( - &mut self, - content: &str, - start: &str, - end: Option<&str>, - ) -> Result { - let token = self.peek_previous()?; - let start_pos = token.start().unwrap_or(0); - - // Only treat Django comments as Comment nodes - if start == "{#" && end == Some("#}") { - Ok(Node::Comment { - content: content.to_string(), - span: Span::new(start_pos, token.token_type().len().unwrap_or(0) as u32), - }) - } else { - self.parse_text() - } - } - fn peek(&self) -> Result { self.peek_at(0) } diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap index ec83ae1..e91cd00 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap @@ -185,10 +185,10 @@ nodes: assignment: ~ nodes: - Text: - content: " (no groups)" + content: (no groups) span: - start: 290 - length: 19 + start: 298 + length: 11 closing: Closing: tag: @@ -218,10 +218,10 @@ nodes: assignment: ~ nodes: - Text: - content: " Guest" + content: Guest span: - start: 338 - length: 9 + start: 342 + length: 5 closing: Closing: tag: diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap index ea238a9..5fc20f6 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap @@ -9,10 +9,10 @@ nodes: start: 0 length: 23 - Text: - content: "

Header

" + content: "

Header

" span: - start: 24 - length: 19 + start: 28 + length: 15 - Block: Block: tag: @@ -34,10 +34,10 @@ nodes: start: 87 length: 43 - Text: - content: "

Welcome " + content: "

Welcome " span: - start: 131 - length: 19 + start: 139 + length: 11 - Variable: bits: - user @@ -52,10 +52,10 @@ nodes: start: 165 length: 4 - Text: - content: "

" + content: "
" span: - start: 170 - length: 13 + start: 178 + length: 5 - Comment: content: "This div is unclosed which doesn't matter" span: @@ -79,10 +79,10 @@ nodes: assignment: ~ nodes: - Text: - content: " " + content: "" span: - start: 276 - length: 18 + start: 288 + length: 6 - Variable: bits: - item @@ -110,10 +110,10 @@ nodes: assignment: ~ assignments: ~ - Text: - content: "
Page Footer
" + content: "
Page Footer
" span: - start: 333 - length: 32 + start: 337 + length: 28 - Text: content: "
" span: diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap index c2657c0..b85e761 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap @@ -14,85 +14,85 @@ nodes: start: 16 length: 6 - Text: - content: " " + content: "" span: - start: 23 - length: 10 + start: 27 + length: 6 - Text: - content: " " + content: "" span: - start: 134 - length: 16 + start: 142 + length: 8 - Text: - content: " " - span: - start: 313 - length: 17 - - Text: - content: " " - span: - start: 331 + start: 286 length: 11 - Text: - content: " " + content: "};" span: - start: 343 - length: 10 + start: 310 + length: 2 + - Text: + content: "" + span: + start: 321 + length: 9 + - Text: + content: "" + span: + start: 335 + length: 7 + - Text: + content: "" + span: + start: 347 + length: 6 - Text: content: "" span: start: 362 length: 23 - Text: - content: "
" + content: "
" span: - start: 386 - length: 64 + start: 394 + length: 56 - Block: Block: tag: @@ -114,10 +114,10 @@ nodes: start: 510 length: 21 - Text: - content: "

Welcome, " + content: "

Welcome, " span: - start: 532 - length: 29 + start: 548 + length: 13 - Variable: bits: - user @@ -158,10 +158,10 @@ nodes: assignment: ~ nodes: - Text: - content: " Admin" + content: "Admin" span: - start: 644 - length: 38 + start: 664 + length: 18 - Block: Branch: tag: @@ -177,10 +177,10 @@ nodes: assignment: ~ nodes: - Text: - content: " User" + content: "User" span: - start: 710 - length: 37 + start: 730 + length: 17 closing: Closing: tag: @@ -210,15 +210,15 @@ nodes: assignment: ~ assignments: ~ - Text: - content: "

" + content: "
" span: - start: 800 - length: 14 + start: 808 + length: 6 - Text: - content: " " + content: "" span: - start: 815 - length: 11 + start: 819 + length: 7 - Text: content: "" span: diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__script__parse_script.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__script__parse_script.snap index b3290d2..0e2543a 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__script__parse_script.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__script__parse_script.snap @@ -14,20 +14,20 @@ nodes: start: 36 length: 22 - Text: - content: " const x = 1;" + content: const x = 1; span: - start: 59 - length: 16 + start: 63 + length: 12 - Text: content: "/* Multi-line\n comment */" span: start: 80 length: 32 - Text: - content: " console.log(x);" + content: console.log(x); span: - start: 113 - length: 19 + start: 117 + length: 15 - Text: content: "" span: diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap index 0238992..447ced8 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap @@ -14,20 +14,20 @@ nodes: start: 28 length: 19 - Text: - content: " .header {" + content: ".header {" span: - start: 48 - length: 13 + start: 52 + length: 9 - Text: - content: " color: blue;" + content: "color: blue;" span: - start: 62 - length: 20 + start: 70 + length: 12 - Text: - content: " }" + content: "}" span: - start: 83 - length: 5 + start: 87 + length: 1 - Text: content: "" span: