This commit is contained in:
Josh Thomas 2025-01-05 01:38:30 -06:00
parent a99ec2d86f
commit b3f80eaeb3
43 changed files with 1220 additions and 75 deletions

View file

@ -42,7 +42,7 @@ impl Ast {
} }
#[derive(Clone, Default, Debug, Serialize)] #[derive(Clone, Default, Debug, Serialize)]
pub struct LineOffsets(Vec<u32>); pub struct LineOffsets(pub Vec<u32>);
impl LineOffsets { impl LineOffsets {
pub fn new() -> Self { pub fn new() -> Self {
@ -55,11 +55,33 @@ impl LineOffsets {
} }
pub fn position_to_line_col(&self, offset: u32) -> (u32, u32) { pub fn position_to_line_col(&self, offset: u32) -> (u32, u32) {
eprintln!("LineOffsets: Converting position {} to line/col. Offsets: {:?}", offset, self.0);
// Find which line contains this offset by looking for the first line start
// that's greater than our position
let line = match self.0.binary_search(&offset) { let line = match self.0.binary_search(&offset) {
Ok(line) => line, Ok(exact_line) => exact_line, // We're exactly at a line start, so we're on that line
Err(line) => if line > 0 { line - 1 } else { line }, Err(next_line) => {
if next_line == 0 {
0 // Before first line start, so we're on line 0
} else {
let prev_line = next_line - 1;
// If we're at the start of the next line, we're on that line
if offset == self.0[next_line] - 1 {
prev_line
} else {
// Otherwise we're on the previous line
prev_line
}
}
}
}; };
// Calculate column as offset from line start
let col = offset - self.0[line]; let col = offset - self.0[line];
eprintln!("LineOffsets: Found line {} starting at offset {}", line, self.0[line]);
eprintln!("LineOffsets: Calculated col {} as {} - {}", col, offset, self.0[line]);
(line as u32, col) (line as u32, col)
} }
@ -185,6 +207,7 @@ mod tests {
fn test_variable_spans() { fn test_variable_spans() {
let template = "Hello\n{{ user.name }}\nWorld"; let template = "Hello\n{{ user.name }}\nWorld";
let tokens = Lexer::new(template).tokenize().unwrap(); let tokens = Lexer::new(template).tokenize().unwrap();
println!("Tokens: {:#?}", tokens); // Add debug print
let mut parser = Parser::new(tokens); let mut parser = Parser::new(tokens);
let ast = parser.parse().unwrap(); let ast = parser.parse().unwrap();
@ -236,6 +259,8 @@ mod tests {
// Check content span // Check content span
if let Some(content) = children { if let Some(content) = children {
if let Node::Text { span, .. } = &content[0] { if let Node::Text { span, .. } = &content[0] {
eprintln!("content {:?}", content);
eprintln!("span start {:?}", span.start());
let (content_line, content_col) = let (content_line, content_col) =
ast.line_offsets.position_to_line_col(*span.start()); ast.line_offsets.position_to_line_col(*span.start());
assert_eq!( assert_eq!(

View file

@ -60,8 +60,11 @@ impl Lexer {
}, },
'\n' => { '\n' => {
self.consume()?; self.consume()?;
let token = TokenType::Newline;
eprintln!("Lexer: Found newline at position {}, incrementing line from {} to {}",
self.start, self.line, self.line + 1);
self.line += 1; self.line += 1;
TokenType::Newline token
} }
' ' | '\t' | '\r' => { ' ' | '\t' | '\r' => {
let mut count = 1; let mut count = 1;

View file

@ -15,21 +15,25 @@ impl Parser {
pub fn parse(&mut self) -> Result<Ast, ParserError> { pub fn parse(&mut self) -> Result<Ast, ParserError> {
let mut ast = Ast::default(); let mut ast = Ast::default();
let mut line_offsets = LineOffsets::new(); let mut line_offsets = LineOffsets::new(); // Already contains [0]
// First pass: collect line offsets // First pass: collect line offsets
let mut current_offset = 0;
for token in self.tokens.tokens() { for token in self.tokens.tokens() {
match token.token_type() { match token.token_type() {
TokenType::Newline => { TokenType::Newline => {
current_offset += 1; // Add 1 for the newline character if let Some(start) = token.start() {
line_offsets.add_line(current_offset as u32); eprintln!("Parser: Found newline at position {}", start);
} // Add line offset at the start of the next line
_ => { line_offsets.add_line(*start as u32 + 1);
if let Some(len) = token.token_type().len() { eprintln!("Parser: Added line offset {} at position {}", line_offsets.0.len(), start + 1);
current_offset += len;
} }
} }
TokenType::Whitespace(count) => {
if let Some(start) = token.start() {
eprintln!("Parser: Found whitespace of length {} at position {}", count, start);
}
}
_ => {}
} }
} }
@ -189,20 +193,21 @@ impl Parser {
} }
let closing_token = self.peek_previous()?; let closing_token = self.peek_previous()?;
let closing_content = match closing_token.token_type() { let closing_content = match closing_token.token_type() {
TokenType::DjangoBlock(content) => content.len(), TokenType::DjangoBlock(content) => content.len() + 5, // Add 5 for {% and %}
_ => 0, _ => 0,
}; };
total_length = (closing_token.start().unwrap_or(0) + closing_content) let closing_start = closing_token.start().unwrap_or(0);
- start_pos as usize; total_length = (closing_start + closing_content) - start_pos as usize;
let closing_span = Span::new(
closing_start as u32,
closing_content as u16,
);
children.push(Node::Block { children.push(Node::Block {
block_type: BlockType::Closing, block_type: BlockType::Closing,
name: tag, name: tag,
bits: vec![], bits: vec![],
children: None, children: None,
span: Span::new( span: closing_span,
closing_token.start().unwrap_or(0) as u32,
closing_content as u16,
),
tag_span, tag_span,
}); });
found_closing_tag = true; found_closing_tag = true;
@ -210,7 +215,7 @@ impl Parser {
} }
// Check if intermediate tag // Check if intermediate tag
if let Some(branches) = &spec.branches { if let Some(branches) = &spec.branches {
if let Some(branch) = branches.iter().find(|i| i.name == tag) { if let Some(branch) = branches.iter().find(|b| b.name == tag) {
// If we have a current branch, add it to children // If we have a current branch, add it to children
if let Some((name, bits, branch_children)) = current_branch { if let Some((name, bits, branch_children)) = current_branch {
let branch_span = Span::new(start_pos, total_length as u16); let branch_span = Span::new(start_pos, total_length as u16);
@ -281,10 +286,11 @@ impl Parser {
} }
fn parse_django_variable(&mut self, s: &str) -> Result<Node, ParserError> { fn parse_django_variable(&mut self, s: &str) -> Result<Node, ParserError> {
let start_token = self.peek_previous()?; let token = self.peek_previous()?;
let start_pos = start_token.start().unwrap_or(0) as u32; let start_pos = token.start().unwrap_or(0) as u32;
let s = s.trim(); // Trim whitespace
let length = s.len() as u16; let length = s.len() as u16;
let span = Span::new(start_pos, length); let span = Span::new(start_pos + 3, length); // Add 3 to skip "{{ "
let parts: Vec<&str> = s.split('|').collect(); let parts: Vec<&str> = s.split('|').collect();
let bits: Vec<String> = parts[0].trim().split('.').map(String::from).collect(); let bits: Vec<String> = parts[0].trim().split('.').map(String::from).collect();
@ -324,10 +330,30 @@ impl Parser {
} }
fn parse_text(&mut self) -> Result<Node, ParserError> { fn parse_text(&mut self) -> Result<Node, ParserError> {
let start_token = self.peek()?; let mut start_pos = self.peek()?.start().unwrap_or(0) as u32;
let start_pos = start_token.start().unwrap_or(0) as u32;
let mut text = String::new(); let mut text = String::new();
// Skip any leading newlines and whitespace
while let Ok(token) = self.peek() {
match token.token_type() {
TokenType::Newline => {
self.consume()?;
text.push('\n');
if let Ok(next) = self.peek() {
start_pos = next.start().unwrap_or(0) as u32;
}
}
TokenType::Whitespace(len) => {
self.consume()?;
text.push_str(&" ".repeat(*len));
if let Ok(next) = self.peek() {
start_pos = next.start().unwrap_or(0) as u32;
}
}
_ => break,
}
}
while let Ok(token) = self.peek() { while let Ok(token) = self.peek() {
match token.token_type() { match token.token_type() {
TokenType::DjangoBlock(_) TokenType::DjangoBlock(_)
@ -530,7 +556,8 @@ mod tests {
} }
#[test] #[test]
fn test_parse_complex_if_elif() { fn test_parse_complex_if_elif() {
let source = "{% if x > 0 %}Positive{% elif x < 0 %}Negative{% else %}Zero{% endif %}"; let source =
"{% if x > 0 %}Positive{% elif x < 0 %}Negative{% else %}Zero{% endif %}";
let tokens = Lexer::new(source).tokenize().unwrap(); let tokens = Lexer::new(source).tokenize().unwrap();
let mut parser = Parser::new(tokens); let mut parser = Parser::new(tokens);
let ast = parser.parse().unwrap(); let ast = parser.parse().unwrap();
@ -734,6 +761,7 @@ mod tests {
let ast = parser.parse().unwrap(); let ast = parser.parse().unwrap();
let offsets = ast.line_offsets(); let offsets = ast.line_offsets();
eprintln!("{:?}", offsets);
assert_eq!(offsets.position_to_line_col(0), (0, 0)); // Start of line 1 assert_eq!(offsets.position_to_line_col(0), (0, 0)); // Start of line 1
assert_eq!(offsets.position_to_line_col(6), (1, 0)); // Start of line 2 assert_eq!(offsets.position_to_line_col(6), (1, 0)); // Start of line 2
} }

View file

@ -15,4 +15,5 @@ nodes:
length: 18 length: 18
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,20 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 608
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!-- HTML comment -->"
span:
start: 0
length: 21
- Comment:
content: Django comment
span:
start: 21
length: 18
line_offsets:
- 0
errors: []

View file

@ -71,4 +71,5 @@ nodes:
length: 8 length: 8
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,76 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 535
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: if
bits:
- if
- x
- ">"
- "0"
children:
- Text:
content: Positive
span:
start: 14
length: 8
- Block:
block_type: Branch
name: elif
bits:
- x
- "<"
- "0"
children:
- Text:
content: Negative
span:
start: 38
length: 8
span:
start: 0
length: 8
tag_span:
start: 0
length: 8
- Block:
block_type: Branch
name: else
bits: []
children:
- Text:
content: Zero
span:
start: 56
length: 4
span:
start: 0
length: 8
tag_span:
start: 0
length: 8
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 60
length: 5
tag_span:
start: 0
length: 8
span:
start: 0
length: 65
tag_span:
start: 0
length: 8
line_offsets:
- 0
errors: []

View file

@ -17,7 +17,7 @@ nodes:
- item - item
filters: [] filters: []
span: span:
start: 23 start: 25
length: 4 length: 4
- Block: - Block:
block_type: Branch block_type: Branch
@ -54,4 +54,5 @@ nodes:
length: 17 length: 17
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,59 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 527
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: for
bits:
- for
- item
- in
- items
children:
- Variable:
bits:
- item
filters: []
span:
start: 26
length: 4
- Block:
block_type: Branch
name: empty
bits: []
children:
- Text:
content: No items
span:
start: 44
length: 8
span:
start: 0
length: 17
tag_span:
start: 0
length: 17
- Block:
block_type: Closing
name: endfor
bits: []
children: ~
span:
start: 52
length: 6
tag_span:
start: 0
length: 17
span:
start: 0
length: 58
tag_span:
start: 0
length: 17
line_offsets:
- 0
errors: []

View file

@ -34,4 +34,5 @@ nodes:
length: 24 length: 24
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,39 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 519
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_authenticated
children:
- Text:
content: Welcome
span:
start: 30
length: 7
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 37
length: 5
tag_span:
start: 0
length: 24
span:
start: 0
length: 42
tag_span:
start: 0
length: 24
line_offsets:
- 0
errors: []

View file

@ -11,11 +11,12 @@ nodes:
- name: title - name: title
arguments: [] arguments: []
span: span:
start: 10 start: 12
length: 5 length: 5
span: span:
start: 0 start: 2
length: 15 length: 15
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,23 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 503
expression: ast
snapshot_kind: text
---
nodes:
- Variable:
bits:
- user
- name
filters:
- name: title
arguments: []
span:
start: 10
length: 5
span:
start: 3
length: 15
line_offsets:
- 0
errors: []

View file

@ -11,21 +11,22 @@ nodes:
arguments: arguments:
- "'nothing'" - "'nothing'"
span: span:
start: 6 start: 8
length: 17 length: 17
- name: title - name: title
arguments: [] arguments: []
span: span:
start: 24 start: 26
length: 5 length: 5
- name: upper - name: upper
arguments: [] arguments: []
span: span:
start: 30 start: 32
length: 5 length: 5
span: span:
start: 0 start: 2
length: 35 length: 35
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,33 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 511
expression: ast
snapshot_kind: text
---
nodes:
- Variable:
bits:
- value
filters:
- name: default
arguments:
- "'nothing'"
span:
start: 6
length: 17
- name: title
arguments: []
span:
start: 24
length: 5
- name: upper
arguments: []
span:
start: 30
length: 5
span:
start: 3
length: 35
line_offsets:
- 0
errors: []

View file

@ -28,16 +28,16 @@ nodes:
- name: title - name: title
arguments: [] arguments: []
span: span:
start: 54 start: 56
length: 5 length: 5
- name: default - name: default
arguments: arguments:
- "'Guest'" - "'Guest'"
span: span:
start: 60 start: 62
length: 15 length: 15
span: span:
start: 44 start: 46
length: 31 length: 31
- Text: - Text:
content: "\n " content: "\n "
@ -98,7 +98,7 @@ nodes:
- name - name
filters: [] filters: []
span: span:
start: 168 start: 170
length: 10 length: 10
- Text: - Text:
content: "\n " content: "\n "
@ -252,16 +252,17 @@ nodes:
length: 1 length: 1
line_offsets: line_offsets:
- 0 - 0
- 34 - 0
- 70 - 40
- 99 - 82
- 130 - 117
- 149 - 160
- 184 - 185
- 214 - 232
- 224 - 274
- 244 - 290
- 255 - 310
- 260 - 327
- 270 - 338
- 348
errors: [] errors: []

View file

@ -0,0 +1,269 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 564
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "Welcome, "
span:
start: 0
length: 9
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_authenticated
children:
- Text:
content: "\n "
span:
start: 39
length: 5
- Variable:
bits:
- user
- name
filters:
- name: title
arguments: []
span:
start: 54
length: 5
- name: default
arguments:
- "'Guest'"
span:
start: 60
length: 15
span:
start: 47
length: 31
- Text:
content: "\n "
span:
start: 81
length: 5
- Block:
block_type: Standard
name: for
bits:
- for
- group
- in
- user.groups
children:
- Text:
content: "\n "
span:
start: 116
length: 9
- Block:
block_type: Standard
name: if
bits:
- if
- forloop.first
children:
- Text:
content: (
span:
start: 147
length: 1
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 148
length: 5
tag_span:
start: 125
length: 16
span:
start: 125
length: 28
tag_span:
start: 125
length: 16
- Text:
content: "\n "
span:
start: 159
length: 9
- Variable:
bits:
- group
- name
filters: []
span:
start: 171
length: 10
- Text:
content: "\n "
span:
start: 184
length: 9
- Block:
block_type: Standard
name: if
bits:
- if
- not
- forloop.last
children:
- Text:
content: ", "
span:
start: 218
length: 2
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 220
length: 5
tag_span:
start: 193
length: 19
span:
start: 193
length: 32
tag_span:
start: 193
length: 19
- Text:
content: "\n "
span:
start: 231
length: 9
- Block:
block_type: Standard
name: if
bits:
- if
- forloop.last
children:
- Text:
content: )
span:
start: 261
length: 1
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 262
length: 5
tag_span:
start: 240
length: 15
span:
start: 240
length: 27
tag_span:
start: 240
length: 15
- Text:
content: "\n "
span:
start: 273
length: 5
- Block:
block_type: Branch
name: empty
bits: []
children:
- Text:
content: "\n (no groups)\n "
span:
start: 289
length: 25
span:
start: 86
length: 24
tag_span:
start: 86
length: 24
- Block:
block_type: Closing
name: endfor
bits: []
children: ~
span:
start: 314
length: 6
tag_span:
start: 86
length: 24
span:
start: 86
length: 234
tag_span:
start: 86
length: 24
- Text:
content: "\n"
span:
start: 326
length: 1
- Block:
block_type: Branch
name: else
bits: []
children:
- Text:
content: "\n Guest\n"
span:
start: 337
length: 11
span:
start: 9
length: 24
tag_span:
start: 9
length: 24
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 348
length: 5
tag_span:
start: 9
length: 24
span:
start: 9
length: 344
tag_span:
start: 9
length: 24
- Text:
content: "!"
span:
start: 359
length: 1
line_offsets:
- 0
- 40
- 82
- 117
- 160
- 185
- 232
- 274
- 290
- 310
- 327
- 338
- 348
errors: []

View file

@ -25,7 +25,7 @@ nodes:
- name - name
filters: [] filters: []
span: span:
start: 43 start: 45
length: 9 length: 9
- Block: - Block:
block_type: Closing block_type: Closing
@ -63,4 +63,5 @@ nodes:
length: 17 length: 17
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,68 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 544
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: for
bits:
- for
- item
- in
- items
children:
- Block:
block_type: Standard
name: if
bits:
- if
- item.active
children:
- Variable:
bits:
- item
- name
filters: []
span:
start: 46
length: 9
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 58
length: 5
tag_span:
start: 23
length: 14
span:
start: 23
length: 40
tag_span:
start: 23
length: 14
- Block:
block_type: Closing
name: endfor
bits: []
children: ~
span:
start: 69
length: 6
tag_span:
start: 0
length: 17
span:
start: 0
length: 75
tag_span:
start: 0
length: 17
line_offsets:
- 0
errors: []

View file

@ -36,7 +36,7 @@ nodes:
- name - name
filters: [] filters: []
span: span:
start: 150 start: 152
length: 9 length: 9
- Text: - Text:
content: "</p>\n <div>\n " content: "</p>\n <div>\n "
@ -72,7 +72,7 @@ nodes:
- item - item
filters: [] filters: []
span: span:
start: 294 start: 296
length: 4 length: 4
- Text: - Text:
content: "</span>\n " content: "</span>\n "
@ -108,17 +108,18 @@ nodes:
start: 48 start: 48
length: 24 length: 24
line_offsets: line_offsets:
- 0
- 0 - 0
- 24 - 24
- 44 - 44
- 73 - 79
- 123 - 131
- 156
- 170 - 170
- 228 - 184
- 254 - 244
- 284 - 276
- 299 - 312
- 332 - 333
- 366
errors: errors:
- UnclosedTag: if - UnclosedTag: if

View file

@ -0,0 +1,126 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 677
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div class=\"container\">\n <h1>Header</h1>\n "
span:
start: 0
length: 48
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_authenticated
children:
- Text:
content: "\n "
span:
start: 78
length: 9
- Comment:
content: This if is unclosed which does matter
span:
start: 87
length: 41
- Text:
content: "\n <p>Welcome "
span:
start: 130
length: 20
- Variable:
bits:
- user
- name
filters: []
span:
start: 153
length: 9
- Text:
content: "</p>\n <div>\n "
span:
start: 165
length: 31
- Comment:
content: "This div is unclosed which doesn't matter"
span:
start: 196
length: 45
- Text:
content: "\n "
span:
start: 243
length: 9
- Block:
block_type: Standard
name: for
bits:
- for
- item
- in
- items
children:
- Text:
content: "\n <span>"
span:
start: 275
length: 19
- Variable:
bits:
- item
filters: []
span:
start: 297
length: 4
- Text:
content: "</span>\n "
span:
start: 304
length: 16
- Block:
block_type: Closing
name: endfor
bits: []
children: ~
span:
start: 320
length: 6
tag_span:
start: 252
length: 17
span:
start: 252
length: 74
tag_span:
start: 252
length: 17
- Text:
content: "\n <footer>Page Footer</footer>\n</div>"
span:
start: 332
length: 40
span:
start: 48
length: 24
tag_span:
start: 48
length: 24
line_offsets:
- 0
- 24
- 44
- 79
- 131
- 170
- 184
- 244
- 276
- 312
- 333
- 366
errors:
- UnclosedTag: if

View file

@ -18,7 +18,7 @@ nodes:
- name - name
filters: [] filters: []
span: span:
start: 23 start: 25
length: 9 length: 9
span: span:
start: 0 start: 0
@ -28,5 +28,6 @@ nodes:
length: 17 length: 17
line_offsets: line_offsets:
- 0 - 0
- 0
errors: errors:
- UnclosedTag: for - UnclosedTag: for

View file

@ -0,0 +1,34 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 638
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: for
bits:
- for
- item
- in
- items
children:
- Variable:
bits:
- item
- name
filters: []
span:
start: 26
length: 9
span:
start: 0
length: 17
tag_span:
start: 0
length: 17
line_offsets:
- 0
errors:
- UnclosedTag: for

View file

@ -23,5 +23,6 @@ nodes:
length: 24 length: 24
line_offsets: line_offsets:
- 0 - 0
- 0
errors: errors:
- UnclosedTag: if - UnclosedTag: if

View file

@ -0,0 +1,29 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 628
expression: ast
snapshot_kind: text
---
nodes:
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_authenticated
children:
- Text:
content: Welcome
span:
start: 30
length: 7
span:
start: 0
length: 24
tag_span:
start: 0
length: 24
line_offsets:
- 0
errors:
- UnclosedTag: if

View file

@ -10,4 +10,5 @@ nodes:
length: 5 length: 5
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 619
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div>"
span:
start: 0
length: 5
line_offsets:
- 0
errors: []

View file

@ -10,4 +10,5 @@ nodes:
length: 28 length: 28
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 648
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<script>console.log('test');"
span:
start: 0
length: 28
line_offsets:
- 0
errors: []

View file

@ -10,4 +10,5 @@ nodes:
length: 27 length: 27
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 657
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<style>body { color: blue; "
span:
start: 0
length: 27
line_offsets:
- 0
errors: []

View file

@ -38,16 +38,16 @@ nodes:
- name: title - name: title
arguments: [] arguments: []
span: span:
start: 571 start: 573
length: 5 length: 5
- name: default - name: default
arguments: arguments:
- "'Guest'" - "'Guest'"
span: span:
start: 577 start: 579
length: 15 length: 15
span: span:
start: 561 start: 563
length: 31 length: 31
- Text: - Text:
content: "!</h1>\n " content: "!</h1>\n "
@ -127,6 +127,7 @@ nodes:
start: 799 start: 799
length: 35 length: 35
line_offsets: line_offsets:
- 0
- 0 - 0
- 16 - 16
- 23 - 23
@ -146,15 +147,15 @@ line_offsets:
- 354 - 354
- 386 - 386
- 451 - 451
- 488 - 494
- 524 - 532
- 591 - 605
- 624 - 644
- 663 - 683
- 684 - 710
- 722 - 748
- 744 - 776
- 762 - 800
- 777 - 815
- 789 - 827
errors: [] errors: []

View file

@ -0,0 +1,162 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 720
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!DOCTYPE html>\n<html>\n <head>\n <style type=\"text/css\">\n /* Style header */\n .header { color: blue; }\n </style>\n <script type=\"text/javascript\">\n // Init app\n const app = {\n /* Config */\n debug: true\n };\n </script>\n </head>\n <body>\n <!-- Header section -->\n <div class=\"header\" id=\"main\" data-value=\"123\" disabled>\n "
span:
start: 0
length: 463
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_authenticated
children:
- Text:
content: "\n "
span:
start: 493
length: 17
- Comment:
content: Welcome message
span:
start: 510
length: 19
- Text:
content: "\n <h1>Welcome, "
span:
start: 531
length: 30
- Variable:
bits:
- user
- name
filters:
- name: title
arguments: []
span:
start: 571
length: 5
- name: default
arguments:
- "'Guest'"
span:
start: 577
length: 15
span:
start: 564
length: 31
- Text:
content: "!</h1>\n "
span:
start: 598
length: 23
- Block:
block_type: Standard
name: if
bits:
- if
- user.is_staff
children:
- Text:
content: "\n <span>Admin</span>\n "
span:
start: 643
length: 56
- Block:
block_type: Branch
name: else
bits: []
children:
- Text:
content: "\n <span>User</span>\n "
span:
start: 709
length: 55
span:
start: 621
length: 16
tag_span:
start: 621
length: 16
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 764
length: 5
tag_span:
start: 621
length: 16
span:
start: 621
length: 148
tag_span:
start: 621
length: 16
- Text:
content: "\n "
span:
start: 775
length: 13
- Block:
block_type: Closing
name: endif
bits: []
children: ~
span:
start: 788
length: 5
tag_span:
start: 463
length: 24
span:
start: 463
length: 330
tag_span:
start: 463
length: 24
- Text:
content: "\n </div>\n </body>\n</html>"
span:
start: 799
length: 35
line_offsets:
- 0
- 16
- 23
- 34
- 66
- 97
- 134
- 151
- 191
- 215
- 241
- 270
- 298
- 313
- 331
- 343
- 354
- 386
- 451
- 494
- 532
- 605
- 644
- 683
- 710
- 748
- 776
- 800
- 815
- 827
errors: []

View file

@ -10,4 +10,5 @@ nodes:
length: 15 length: 15
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 476
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<!DOCTYPE html>"
span:
start: 0
length: 15
line_offsets:
- 0
errors: []

View file

@ -10,4 +10,5 @@ nodes:
length: 34 length: 34
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 484
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<div class=\"container\">Hello</div>"
span:
start: 0
length: 34
line_offsets:
- 0
errors: []

View file

@ -10,4 +10,5 @@ nodes:
length: 21 length: 21
line_offsets: line_offsets:
- 0 - 0
- 0
errors: [] errors: []

View file

@ -0,0 +1,15 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 492
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<input type=\"text\" />"
span:
start: 0
length: 21
line_offsets:
- 0
errors: []

View file

@ -9,6 +9,7 @@ nodes:
start: 0 start: 0
length: 142 length: 142
line_offsets: line_offsets:
- 0
- 0 - 0
- 32 - 32
- 59 - 59

View file

@ -0,0 +1,21 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 581
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<script type=\"text/javascript\">\n // Single line comment\n const x = 1;\n /* Multi-line\n comment */\n console.log(x);\n</script>"
span:
start: 0
length: 142
line_offsets:
- 0
- 32
- 59
- 76
- 94
- 113
- 133
errors: []

View file

@ -9,6 +9,7 @@ nodes:
start: 0 start: 0
length: 97 length: 97
line_offsets: line_offsets:
- 0
- 0 - 0
- 24 - 24
- 48 - 48

View file

@ -0,0 +1,20 @@
---
source: crates/djls-template-ast/src/parser.rs
assertion_line: 597
expression: ast
snapshot_kind: text
---
nodes:
- Text:
content: "<style type=\"text/css\">\n /* Header styles */\n .header {\n color: blue;\n }\n</style>"
span:
start: 0
length: 97
line_offsets:
- 0
- 24
- 48
- 62
- 83
- 89
errors: []