correctly associate branch children

This commit is contained in:
Josh Thomas 2025-01-04 15:36:57 -06:00
parent ec05c62c2a
commit 1c5740b4f6
5 changed files with 43 additions and 25 deletions

View file

@ -177,16 +177,29 @@ impl Parser {
let tag_spec = specs.get(tag_name.as_str()).cloned(); let tag_spec = specs.get(tag_name.as_str()).cloned();
let mut children = Vec::new(); let mut children = Vec::new();
let mut current_branch: Option<(String, Vec<String>, Vec<Node>)> = None;
while !self.is_at_end() { while !self.is_at_end() {
match self.next_node() { match self.next_node() {
Ok(node) => { Ok(node) => {
children.push(node); if let Some((_, _, branch_children)) = &mut current_branch {
branch_children.push(node);
} else {
children.push(node);
}
} }
Err(ParserError::ErrorSignal(Signal::SpecialTag(tag))) => { Err(ParserError::ErrorSignal(Signal::SpecialTag(tag))) => {
if let Some(spec) = &tag_spec { if let Some(spec) = &tag_spec {
// Check if closing tag // Check if closing tag
if Some(&tag) == spec.closing.as_ref() { if Some(&tag) == spec.closing.as_ref() {
// If we have a current branch, add it to children
if let Some((name, bits, branch_children)) = current_branch {
children.push(Node::Django(DjangoNode::Tag(TagNode::Branch {
name,
bits,
children: branch_children,
})));
}
children.push(Node::Django(DjangoNode::Tag(TagNode::Closing { children.push(Node::Django(DjangoNode::Tag(TagNode::Closing {
name: tag, name: tag,
bits: vec![], bits: vec![],
@ -200,7 +213,15 @@ impl Parser {
// Check if intermediate tag // Check if intermediate tag
if let Some(intermediates) = &spec.intermediates { if let Some(intermediates) = &spec.intermediates {
if let Some(intermediate) = intermediates.iter().find(|i| i.name == tag) { if let Some(intermediate) = intermediates.iter().find(|i| i.name == tag) {
// Create branch node with the current children // If we have a current branch, add it to children
if let Some((name, bits, branch_children)) = current_branch {
children.push(Node::Django(DjangoNode::Tag(TagNode::Branch {
name,
bits,
children: branch_children,
})));
}
// Create new branch node
let branch_bits = if intermediate.args { let branch_bits = if intermediate.args {
match &self.tokens[self.current - 1].token_type() { match &self.tokens[self.current - 1].token_type() {
TokenType::DjangoBlock(content) => content TokenType::DjangoBlock(content) => content
@ -213,11 +234,7 @@ impl Parser {
} else { } else {
vec![] vec![]
}; };
children.push(Node::Django(DjangoNode::Tag(TagNode::Branch { current_branch = Some((tag, branch_bits, Vec::new()));
name: tag,
bits: branch_bits,
children: Vec::new(),
})));
continue; continue;
} }
} }
@ -666,7 +683,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();

View file

@ -22,15 +22,15 @@ nodes:
- x - x
- "<" - "<"
- "0" - "0"
children: [] children:
- Text: Negative - Text: Negative
- Django: - Django:
Tag: Tag:
Branch: Branch:
name: else name: else
bits: [] bits: []
children: [] children:
- Text: Zero - Text: Zero
- Django: - Django:
Tag: Tag:
Closing: Closing:

View file

@ -23,8 +23,8 @@ nodes:
Branch: Branch:
name: empty name: empty
bits: [] bits: []
children: [] children:
- Text: No items - Text: No items
- Django: - Django:
Tag: Tag:
Closing: Closing:

View file

@ -87,8 +87,8 @@ nodes:
Branch: Branch:
name: empty name: empty
bits: [] bits: []
children: [] children:
- Text: (no groups) - Text: (no groups)
- Django: - Django:
Tag: Tag:
Closing: Closing:
@ -99,8 +99,8 @@ nodes:
Branch: Branch:
name: else name: else
bits: [] bits: []
children: [] children:
- Text: Guest - Text: Guest
- Django: - Django:
Tag: Tag:
Closing: Closing:

View file

@ -111,13 +111,13 @@ nodes:
Branch: Branch:
name: else name: else
bits: [] bits: []
children: [] children:
- Html: - Html:
Element: Element:
tag_name: span tag_name: span
attributes: {} attributes: {}
children: children:
- Text: User - Text: User
- Django: - Django:
Tag: Tag:
Closing: Closing: