Layout XML text nodes are now parsed template strings instead of raw text containing {{template tags}}
This commit is contained in:
parent
214c1c09ac
commit
3205e8d274
|
|
@ -1,6 +1,7 @@
|
|||
use crate::layout_abstract_types::*;
|
||||
|
||||
// AST for a component with info on its definition (from the root element of the XML layout) and a vector of direct child component tags
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct FlatComponent {
|
||||
// The abstract definition of the root node of the component with attribute parameters
|
||||
pub own_info: LayoutComponentDefinition,
|
||||
|
|
@ -48,7 +49,7 @@ pub type NodeOrDefTree = rctree::Node<LayoutComponentNodeOrDefinition>;
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum LayoutComponentNode {
|
||||
Tag(LayoutComponentTag),
|
||||
Text(String),
|
||||
Text(Vec<TemplateStringSegment>),
|
||||
}
|
||||
|
||||
impl LayoutComponentNode {
|
||||
|
|
@ -58,7 +59,7 @@ impl LayoutComponentNode {
|
|||
}
|
||||
|
||||
/// Given some text hanging out in the XML between tags, construct a `LayoutComponentNode` with that text which simply stores the provided `String`
|
||||
pub fn new_text(text: String) -> Self {
|
||||
pub fn new_text(text: Vec<TemplateStringSegment>) -> Self {
|
||||
Self::Text(text)
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ impl LayoutComponentNode {
|
|||
pub fn debug_print(&self) {
|
||||
match self {
|
||||
LayoutComponentNode::Tag(tag) => tag.debug_print(),
|
||||
LayoutComponentNode::Text(text) => println!("================> Text Node: {}", text),
|
||||
LayoutComponentNode::Text(text) => println!("================> Text Node: {:#?}", text),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,24 +157,7 @@ impl AttributeParser {
|
|||
Some([height]) if height.eq_ignore_ascii_case("height") => TypeValueOrArgument::TypeValue(TypeValue::Dimension(Dimension::Height)),
|
||||
// TemplateString: `? ... {{?}} ...`
|
||||
Some(["`", string, "`"]) => {
|
||||
let mut segments = Vec::<TemplateStringSegment>::new();
|
||||
let mut is_template = false;
|
||||
|
||||
// Alternate between string and handlebars, always starting wtih string even if empty, and push abstract tokens of non-empty ones to the TemplateString sequence
|
||||
for part in self.split_by_string_templates_regex.split(string) {
|
||||
// Push only non-empty template string segments (a String or Argument)
|
||||
if !part.is_empty() {
|
||||
// Based on whether we are alternating to a string or template, push the appropriate abstract token
|
||||
let segment = match is_template {
|
||||
false => TemplateStringSegment::String(String::from(part)),
|
||||
true => TemplateStringSegment::Argument(TypeValueOrArgument::VariableArgument(String::from(part))),
|
||||
};
|
||||
segments.push(segment);
|
||||
}
|
||||
|
||||
// The next iteration will switch from a template to a string or vice versa
|
||||
is_template = !is_template;
|
||||
}
|
||||
let segments = self.parse_text_template_sequence(string);
|
||||
|
||||
TypeValueOrArgument::TypeValue(TypeValue::TemplateString(segments))
|
||||
},
|
||||
|
|
@ -299,6 +282,30 @@ impl AttributeParser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Extract {{template tags}} from surrounding text and return a vector alternating between text and the argument
|
||||
pub fn parse_text_template_sequence(&self, input_text: &str) -> Vec<TemplateStringSegment> {
|
||||
let mut segments = Vec::<TemplateStringSegment>::new();
|
||||
let mut is_template = false;
|
||||
|
||||
// Alternate between string and handlebars, always starting wtih string even if empty, and push abstract tokens of non-empty ones to the TemplateString sequence
|
||||
for part in self.split_by_string_templates_regex.split(input_text) {
|
||||
// Push only non-empty template string segments (a String or Argument)
|
||||
if !part.is_empty() {
|
||||
// Based on whether we are alternating to a string or template, push the appropriate abstract token
|
||||
let segment = match is_template {
|
||||
false => TemplateStringSegment::String(String::from(part)),
|
||||
true => TemplateStringSegment::Argument(TypeValueOrArgument::VariableArgument(String::from(part))),
|
||||
};
|
||||
segments.push(segment);
|
||||
}
|
||||
|
||||
// The next iteration will switch from a template to a string or vice versa
|
||||
is_template = !is_template;
|
||||
}
|
||||
|
||||
segments
|
||||
}
|
||||
|
||||
/// Replace escape characters in an XML string, only supports `&, <, >, ", '`
|
||||
fn unescape_xml(xml: &str) -> String {
|
||||
// Find and replace each escape character, starting with `&` to avoid unescaping other escape sequences
|
||||
|
|
|
|||
|
|
@ -317,7 +317,8 @@ impl LayoutSystem {
|
|||
.expect(&format!("Encountered text outside the root tag when parsing XML layout in component: {}", path)[..]);
|
||||
|
||||
// Construct a text node with the provided text
|
||||
let abstract_text_node = LayoutComponentNodeOrDefinition::LayoutComponentNode(LayoutComponentNode::new_text(text_string));
|
||||
let text_template_sequence = attribute_parser.parse_text_template_sequence(&text_string[..]);
|
||||
let abstract_text_node = LayoutComponentNodeOrDefinition::LayoutComponentNode(LayoutComponentNode::new_text(text_template_sequence));
|
||||
// Put the text node in a new tree node
|
||||
let tree_node = rctree::Node::new(abstract_text_node);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue