Skip to content

Commit 55b2b92

Browse files
leading whitespace
1 parent ad9d6e5 commit 55b2b92

6 files changed

+131
-123
lines changed

crates/djls-template-ast/src/parser.rs

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ impl Parser {
5454
fn next_node(&mut self) -> Result<Node, ParserError> {
5555
let token = self.peek()?;
5656
match token.token_type() {
57+
TokenType::Comment(content, start, end) => {
58+
self.consume()?;
59+
self.parse_comment(content, start, end.as_deref())
60+
}
61+
TokenType::Eof => Err(ParserError::Ast(AstError::StreamError("AtEnd".to_string()))),
5762
TokenType::DjangoBlock(content) => {
5863
self.consume()?;
5964
self.parse_django_block(content)
@@ -62,24 +67,39 @@ impl Parser {
6267
self.consume()?;
6368
self.parse_django_variable(content)
6469
}
65-
TokenType::Comment(content, start, end) => {
66-
self.consume()?;
67-
self.parse_comment(content, start, end.as_deref())
68-
}
69-
TokenType::Text(_)
70-
| TokenType::Whitespace(_)
71-
| TokenType::Newline
70+
TokenType::HtmlTagClose(_)
7271
| TokenType::HtmlTagOpen(_)
73-
| TokenType::HtmlTagClose(_)
7472
| TokenType::HtmlTagVoid(_)
75-
| TokenType::ScriptTagOpen(_)
73+
| TokenType::Newline
7674
| TokenType::ScriptTagClose(_)
75+
| TokenType::ScriptTagOpen(_)
76+
| TokenType::StyleTagClose(_)
7777
| TokenType::StyleTagOpen(_)
78-
| TokenType::StyleTagClose(_) => {
78+
| TokenType::Text(_)
79+
| TokenType::Whitespace(_) => {
7980
self.consume()?;
8081
self.parse_text()
8182
}
82-
TokenType::Eof => Err(ParserError::Ast(AstError::StreamError("AtEnd".to_string()))),
83+
}
84+
}
85+
86+
fn parse_comment(
87+
&mut self,
88+
content: &str,
89+
start: &str,
90+
end: Option<&str>,
91+
) -> Result<Node, ParserError> {
92+
let token = self.peek_previous()?;
93+
let start_pos = token.start().unwrap_or(0);
94+
95+
// Only treat Django comments as Comment nodes
96+
if start == "{#" && end == Some("#}") {
97+
Ok(Node::Comment {
98+
content: content.to_string(),
99+
span: Span::new(start_pos, token.token_type().len().unwrap_or(0) as u32),
100+
})
101+
} else {
102+
self.parse_text()
83103
}
84104
}
85105

@@ -209,7 +229,7 @@ impl Parser {
209229
..
210230
} = &block
211231
{
212-
if let Some(expected_closing) = &spec.closing {
232+
if let Some(_expected_closing) = &spec.closing {
213233
self.errors.push(ParserError::Ast(AstError::UnclosedTag(
214234
tag_ref.name.clone(),
215235
)));
@@ -245,24 +265,32 @@ impl Parser {
245265
filters.push(DjangoFilter {
246266
name: filter_name.to_string(),
247267
args: filter_args,
248-
span: Span::new(start + 4, content.len() as u32), // Account for {{ and space
268+
span: Span::new(start + 4, content.len() as u32),
249269
});
250270
}
251271
}
252272

253273
Ok(Node::Variable {
254274
bits,
255275
filters,
256-
span: Span::new(start + 3, content.len() as u32), // Account for {{ and space
276+
span: Span::new(start + 3, content.len() as u32),
257277
})
258278
}
259279

260280
fn parse_text(&mut self) -> Result<Node, ParserError> {
261281
let start_token = self.peek_previous()?;
262282
let start_pos = start_token.start().unwrap_or(0);
263283

264-
if matches!(start_token.token_type(), TokenType::Newline) {
265-
return self.next_node();
284+
match start_token.token_type() {
285+
TokenType::Newline => return self.next_node(),
286+
TokenType::Whitespace(_)
287+
if self
288+
.peek_at(-2)
289+
.map_or(false, |t| matches!(t.token_type(), TokenType::Newline)) =>
290+
{
291+
return self.next_node()
292+
}
293+
_ => {}
266294
}
267295

268296
let mut text = start_token.token_type().to_string();
@@ -294,26 +322,6 @@ impl Parser {
294322
}
295323
}
296324

297-
fn parse_comment(
298-
&mut self,
299-
content: &str,
300-
start: &str,
301-
end: Option<&str>,
302-
) -> Result<Node, ParserError> {
303-
let token = self.peek_previous()?;
304-
let start_pos = token.start().unwrap_or(0);
305-
306-
// Only treat Django comments as Comment nodes
307-
if start == "{#" && end == Some("#}") {
308-
Ok(Node::Comment {
309-
content: content.to_string(),
310-
span: Span::new(start_pos, token.token_type().len().unwrap_or(0) as u32),
311-
})
312-
} else {
313-
self.parse_text()
314-
}
315-
}
316-
317325
fn peek(&self) -> Result<Token, ParserError> {
318326
self.peek_at(0)
319327
}

crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__django__parse_mixed_content.snap

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,10 @@ nodes:
185185
assignment: ~
186186
nodes:
187187
- Text:
188-
content: " (no groups)"
188+
content: (no groups)
189189
span:
190-
start: 290
191-
length: 19
190+
start: 298
191+
length: 11
192192
closing:
193193
Closing:
194194
tag:
@@ -218,10 +218,10 @@ nodes:
218218
assignment: ~
219219
nodes:
220220
- Text:
221-
content: " Guest"
221+
content: Guest
222222
span:
223-
start: 338
224-
length: 9
223+
start: 342
224+
length: 5
225225
closing:
226226
Closing:
227227
tag:

crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__errors__parse_error_recovery.snap

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ nodes:
99
start: 0
1010
length: 23
1111
- Text:
12-
content: " <h1>Header</h1>"
12+
content: "<h1>Header</h1>"
1313
span:
14-
start: 24
15-
length: 19
14+
start: 28
15+
length: 15
1616
- Block:
1717
Block:
1818
tag:
@@ -34,10 +34,10 @@ nodes:
3434
start: 87
3535
length: 43
3636
- Text:
37-
content: " <p>Welcome "
37+
content: "<p>Welcome "
3838
span:
39-
start: 131
40-
length: 19
39+
start: 139
40+
length: 11
4141
- Variable:
4242
bits:
4343
- user
@@ -52,10 +52,10 @@ nodes:
5252
start: 165
5353
length: 4
5454
- Text:
55-
content: " <div>"
55+
content: "<div>"
5656
span:
57-
start: 170
58-
length: 13
57+
start: 178
58+
length: 5
5959
- Comment:
6060
content: "This div is unclosed which doesn't matter"
6161
span:
@@ -79,10 +79,10 @@ nodes:
7979
assignment: ~
8080
nodes:
8181
- Text:
82-
content: " <span>"
82+
content: "<span>"
8383
span:
84-
start: 276
85-
length: 18
84+
start: 288
85+
length: 6
8686
- Variable:
8787
bits:
8888
- item
@@ -110,10 +110,10 @@ nodes:
110110
assignment: ~
111111
assignments: ~
112112
- Text:
113-
content: " <footer>Page Footer</footer>"
113+
content: "<footer>Page Footer</footer>"
114114
span:
115-
start: 333
116-
length: 32
115+
start: 337
116+
length: 28
117117
- Text:
118118
content: "</div>"
119119
span:

0 commit comments

Comments
 (0)